create new chat
This commit is contained in:
parent
5808368b9a
commit
75e71be14d
24 changed files with 593 additions and 331 deletions
|
|
@ -89,6 +89,7 @@ ChatCore::ChatCore(const std::shared_ptr<linphone::ChatRoom> &chatRoom) : QObjec
|
||||||
}
|
}
|
||||||
resetChatMessageList(messageList);
|
resetChatMessageList(messageList);
|
||||||
mIdentifier = Utils::coreStringToAppString(chatRoom->getIdentifier());
|
mIdentifier = Utils::coreStringToAppString(chatRoom->getIdentifier());
|
||||||
|
mChatRoomState = LinphoneEnums::fromLinphone(chatRoom->getState());
|
||||||
connect(this, &ChatCore::messageListChanged, this, &ChatCore::lUpdateLastMessage);
|
connect(this, &ChatCore::messageListChanged, this, &ChatCore::lUpdateLastMessage);
|
||||||
connect(this, &ChatCore::messagesInserted, this, &ChatCore::lUpdateLastMessage);
|
connect(this, &ChatCore::messagesInserted, this, &ChatCore::lUpdateLastMessage);
|
||||||
connect(this, &ChatCore::messageRemoved, this, &ChatCore::lUpdateLastMessage);
|
connect(this, &ChatCore::messageRemoved, this, &ChatCore::lUpdateLastMessage);
|
||||||
|
|
@ -132,6 +133,12 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
||||||
});
|
});
|
||||||
mChatModelConnection->makeConnectToModel(
|
mChatModelConnection->makeConnectToModel(
|
||||||
&ChatModel::deleted, [this]() { mChatModelConnection->invokeToCore([this]() { emit deleted(); }); });
|
&ChatModel::deleted, [this]() { mChatModelConnection->invokeToCore([this]() { emit deleted(); }); });
|
||||||
|
mChatModelConnection->makeConnectToModel(
|
||||||
|
&ChatModel::stateChanged,
|
||||||
|
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom, linphone::ChatRoom::State newState) {
|
||||||
|
auto state = LinphoneEnums::fromLinphone(newState);
|
||||||
|
mChatModelConnection->invokeToCore([this, state]() { setChatRoomState(state); });
|
||||||
|
});
|
||||||
|
|
||||||
mChatModelConnection->makeConnectToModel(&ChatModel::chatMessageReceived,
|
mChatModelConnection->makeConnectToModel(&ChatModel::chatMessageReceived,
|
||||||
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||||
|
|
@ -277,6 +284,17 @@ LinphoneEnums::ChatMessageState ChatCore::getLastMessageState() const {
|
||||||
return mLastMessage ? mLastMessage->getMessageState() : LinphoneEnums::ChatMessageState::StateIdle;
|
return mLastMessage ? mLastMessage->getMessageState() : LinphoneEnums::ChatMessageState::StateIdle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinphoneEnums::ChatRoomState ChatCore::getChatRoomState() const {
|
||||||
|
return mChatRoomState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatCore::setChatRoomState(LinphoneEnums::ChatRoomState state) {
|
||||||
|
if (mChatRoomState != state) {
|
||||||
|
mChatRoomState = state;
|
||||||
|
emit chatRoomStateChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ChatMessageGui *ChatCore::getLastMessage() const {
|
ChatMessageGui *ChatCore::getLastMessage() const {
|
||||||
return mLastMessage ? new ChatMessageGui(mLastMessage) : nullptr;
|
return mLastMessage ? new ChatMessageGui(mLastMessage) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ public:
|
||||||
Q_PROPERTY(QString lastMessageText READ getLastMessageText NOTIFY lastMessageChanged)
|
Q_PROPERTY(QString lastMessageText READ getLastMessageText NOTIFY lastMessageChanged)
|
||||||
Q_PROPERTY(ChatMessageGui *lastMessage READ getLastMessage NOTIFY lastMessageChanged)
|
Q_PROPERTY(ChatMessageGui *lastMessage READ getLastMessage NOTIFY lastMessageChanged)
|
||||||
Q_PROPERTY(LinphoneEnums::ChatMessageState lastMessageState READ getLastMessageState NOTIFY lastMessageChanged)
|
Q_PROPERTY(LinphoneEnums::ChatMessageState lastMessageState READ getLastMessageState NOTIFY lastMessageChanged)
|
||||||
|
Q_PROPERTY(LinphoneEnums::ChatRoomState state READ getChatRoomState NOTIFY chatRoomStateChanged)
|
||||||
Q_PROPERTY(int unreadMessagesCount READ getUnreadMessagesCount WRITE setUnreadMessagesCount NOTIFY
|
Q_PROPERTY(int unreadMessagesCount READ getUnreadMessagesCount WRITE setUnreadMessagesCount NOTIFY
|
||||||
unreadMessagesCountChanged)
|
unreadMessagesCountChanged)
|
||||||
Q_PROPERTY(QString composingName READ getComposingName WRITE setComposingName NOTIFY composingUserChanged)
|
Q_PROPERTY(QString composingName READ getComposingName WRITE setComposingName NOTIFY composingUserChanged)
|
||||||
|
|
@ -70,6 +71,9 @@ public:
|
||||||
|
|
||||||
LinphoneEnums::ChatMessageState getLastMessageState() const;
|
LinphoneEnums::ChatMessageState getLastMessageState() const;
|
||||||
|
|
||||||
|
LinphoneEnums::ChatRoomState getChatRoomState() const;
|
||||||
|
void setChatRoomState(LinphoneEnums::ChatRoomState state);
|
||||||
|
|
||||||
QSharedPointer<ChatMessageCore> getLastMessageCore() const;
|
QSharedPointer<ChatMessageCore> getLastMessageCore() const;
|
||||||
void setLastMessage(QSharedPointer<ChatMessageCore> lastMessage);
|
void setLastMessage(QSharedPointer<ChatMessageCore> lastMessage);
|
||||||
|
|
||||||
|
|
@ -96,11 +100,9 @@ public:
|
||||||
|
|
||||||
std::shared_ptr<ChatModel> getModel() const;
|
std::shared_ptr<ChatModel> getModel() const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
signals:
|
||||||
// used to close all the notifications when one is clicked
|
// used to close all the notifications when one is clicked
|
||||||
void messageOpen();
|
void messageOpen();
|
||||||
|
|
||||||
signals:
|
|
||||||
void lastUpdatedTimeChanged(QDateTime time);
|
void lastUpdatedTimeChanged(QDateTime time);
|
||||||
void lastMessageChanged();
|
void lastMessageChanged();
|
||||||
void titleChanged(QString title);
|
void titleChanged(QString title);
|
||||||
|
|
@ -111,6 +113,7 @@ signals:
|
||||||
void avatarUriChanged();
|
void avatarUriChanged();
|
||||||
void deleted();
|
void deleted();
|
||||||
void composingUserChanged();
|
void composingUserChanged();
|
||||||
|
void chatRoomStateChanged();
|
||||||
|
|
||||||
void lDeleteMessage();
|
void lDeleteMessage();
|
||||||
void lDelete();
|
void lDelete();
|
||||||
|
|
@ -134,6 +137,7 @@ private:
|
||||||
QString mComposingName;
|
QString mComposingName;
|
||||||
QString mComposingAddress;
|
QString mComposingAddress;
|
||||||
bool mIsGroupChat = false;
|
bool mIsGroupChat = false;
|
||||||
|
LinphoneEnums::ChatRoomState mChatRoomState;
|
||||||
std::shared_ptr<ChatModel> mChatModel;
|
std::shared_ptr<ChatModel> mChatModel;
|
||||||
QSharedPointer<ChatMessageCore> mLastMessage;
|
QSharedPointer<ChatMessageCore> mLastMessage;
|
||||||
QList<QSharedPointer<ChatMessageCore>> mChatMessageList;
|
QList<QSharedPointer<ChatMessageCore>> mChatMessageList;
|
||||||
|
|
|
||||||
|
|
@ -103,28 +103,6 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
mModelConnection->makeConnectToModel(
|
|
||||||
&CoreModel::chatRoomStateChanged,
|
|
||||||
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
|
||||||
linphone::ChatRoom::State state) {
|
|
||||||
// check account, filter, then add if ok
|
|
||||||
if (chatRoom->getAccount() == core->getDefaultAccount()) {
|
|
||||||
if (state == linphone::ChatRoom::State::Created) {
|
|
||||||
auto list = getSharedList<ChatCore>();
|
|
||||||
auto found =
|
|
||||||
std::find_if(list.begin(), list.end(), [chatRoom](const QSharedPointer<ChatCore> &item) {
|
|
||||||
return (item && item->getModel()->getMonitor() == chatRoom);
|
|
||||||
});
|
|
||||||
if (found == list.end()) {
|
|
||||||
auto model = createChatCore(chatRoom);
|
|
||||||
mModelConnection->invokeToCore([this, model]() {
|
|
||||||
add(model);
|
|
||||||
emit chatAdded();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mModelConnection->makeConnectToModel(
|
mModelConnection->makeConnectToModel(
|
||||||
&CoreModel::defaultAccountChanged,
|
&CoreModel::defaultAccountChanged,
|
||||||
[this](std::shared_ptr<linphone::Core> core, std::shared_ptr<linphone::Account> account) { lUpdate(); });
|
[this](std::shared_ptr<linphone::Core> core, std::shared_ptr<linphone::Account> account) { lUpdate(); });
|
||||||
|
|
@ -146,6 +124,19 @@ int ChatList::findChatIndex(ChatGui *chatGui) {
|
||||||
return it == chatList.end() ? -1 : std::distance(chatList.begin(), it);
|
return it == chatList.end() ? -1 : std::distance(chatList.begin(), it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatList::addChatInList(ChatGui *chatGui) {
|
||||||
|
auto chatCore = chatGui->mCore;
|
||||||
|
auto chatList = getSharedList<ChatCore>();
|
||||||
|
auto it = std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer<ChatCore> item) {
|
||||||
|
return item->getIdentifier() == chatCore->getIdentifier();
|
||||||
|
});
|
||||||
|
if (it == chatList.end()) {
|
||||||
|
connectItem(chatCore);
|
||||||
|
add(chatCore);
|
||||||
|
emit chatAdded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QVariant ChatList::data(const QModelIndex &index, int role) const {
|
QVariant ChatList::data(const QModelIndex &index, int role) const {
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ public:
|
||||||
void connectItem(QSharedPointer<ChatCore> chat);
|
void connectItem(QSharedPointer<ChatCore> chat);
|
||||||
|
|
||||||
int findChatIndex(ChatGui *chat);
|
int findChatIndex(ChatGui *chat);
|
||||||
|
void addChatInList(ChatGui *chatGui);
|
||||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,13 @@ int ChatProxy::findChatIndex(ChatGui *chatGui) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatProxy::addChatInList(ChatGui *chatGui) {
|
||||||
|
auto chatList = getListModel<ChatList>();
|
||||||
|
if (chatList) {
|
||||||
|
chatList->addChatInList(chatGui);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
bool ChatProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||||
// auto l = getItemAtSource<ChatList, ChatCore>(sourceRow);
|
// auto l = getItemAtSource<ChatList, ChatCore>(sourceRow);
|
||||||
// return l != nullptr;
|
// return l != nullptr;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ public:
|
||||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||||
|
|
||||||
Q_INVOKABLE int findChatIndex(ChatGui *chatGui);
|
Q_INVOKABLE int findChatIndex(ChatGui *chatGui);
|
||||||
|
Q_INVOKABLE void addChatInList(ChatGui *chatGui);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void chatRemoved(ChatGui *chat);
|
void chatRemoved(ChatGui *chat);
|
||||||
|
|
|
||||||
|
|
@ -467,11 +467,19 @@ QString ToolModel::computeUserAgent(const std::shared_ptr<linphone::Config> &con
|
||||||
.remove("'");
|
.remove("'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ToolModel::isEndToEndEncryptedChatAvailable() {
|
||||||
|
auto core = CoreModel::getInstance()->getCore();
|
||||||
|
auto defaultAccount = core->getDefaultAccount();
|
||||||
|
return core->limeX3DhEnabled() && defaultAccount && !defaultAccount->getParams()->getLimeServerUrl().empty() &&
|
||||||
|
!defaultAccount->getParams()->getConferenceFactoryUri().empty();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<linphone::ConferenceParams>
|
std::shared_ptr<linphone::ConferenceParams>
|
||||||
ToolModel::getChatRoomParams(std::shared_ptr<linphone::Call> call, std::shared_ptr<linphone::Address> remoteAddress) {
|
ToolModel::getChatRoomParams(std::shared_ptr<linphone::Call> call, std::shared_ptr<linphone::Address> remoteAddress) {
|
||||||
auto core = call ? call->getCore() : CoreModel::getInstance()->getCore();
|
auto core = call ? call->getCore() : CoreModel::getInstance()->getCore();
|
||||||
auto localAddress = call ? call->getCallLog()->getLocalAddress() : nullptr;
|
auto localAddress = call ? call->getCallLog()->getLocalAddress() : nullptr;
|
||||||
if (!remoteAddress && call) remoteAddress = call->getRemoteAddress()->clone();
|
if (!remoteAddress && call) remoteAddress = call->getRemoteAddress()->clone();
|
||||||
|
remoteAddress->clean();
|
||||||
auto account = findAccount(localAddress);
|
auto account = findAccount(localAddress);
|
||||||
if (!account) account = core->getDefaultAccount();
|
if (!account) account = core->getDefaultAccount();
|
||||||
if (!account) qWarning() << "failed to get account, return";
|
if (!account) qWarning() << "failed to get account, return";
|
||||||
|
|
@ -481,7 +489,7 @@ ToolModel::getChatRoomParams(std::shared_ptr<linphone::Call> call, std::shared_p
|
||||||
params->enableChat(true);
|
params->enableChat(true);
|
||||||
params->enableGroup(false);
|
params->enableGroup(false);
|
||||||
//: Dummy subject
|
//: Dummy subject
|
||||||
params->setSubject(Utils::appStringToCoreString(QObject::tr("chat_dummy_subject")));
|
params->setSubject("Dummy subject");
|
||||||
params->setAccount(account);
|
params->setAccount(account);
|
||||||
|
|
||||||
auto chatParams = params->getChatParams();
|
auto chatParams = params->getChatParams();
|
||||||
|
|
@ -498,12 +506,12 @@ ToolModel::getChatRoomParams(std::shared_ptr<linphone::Call> call, std::shared_p
|
||||||
chatParams->setBackend(linphone::ChatRoom::Backend::FlexisipChat);
|
chatParams->setBackend(linphone::ChatRoom::Backend::FlexisipChat);
|
||||||
params->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd);
|
params->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd);
|
||||||
} else if (!accountParams->getInstantMessagingEncryptionMandatory()) {
|
} else if (!accountParams->getInstantMessagingEncryptionMandatory()) {
|
||||||
if (SettingsModel::getInstance()->getCreateEndToEndEncryptedMeetingsAndGroupCalls()) {
|
if (isEndToEndEncryptedChatAvailable()) {
|
||||||
qDebug() << "Account is in interop mode but LIME is available, requesting E2E encryption";
|
qDebug() << "Account is in interop mode but LIME is available, requesting E2E encryption";
|
||||||
chatParams->setBackend(linphone::ChatRoom::Backend::FlexisipChat);
|
chatParams->setBackend(linphone::ChatRoom::Backend::FlexisipChat);
|
||||||
params->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd);
|
params->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Account is in interop mode and LIME is available, disabling E2E encryption";
|
qDebug() << "Account is in interop mode and LIME is not available, disabling E2E encryption";
|
||||||
chatParams->setBackend(linphone::ChatRoom::Backend::Basic);
|
chatParams->setBackend(linphone::ChatRoom::Backend::Basic);
|
||||||
params->setSecurityLevel(linphone::Conference::SecurityLevel::None);
|
params->setSecurityLevel(linphone::Conference::SecurityLevel::None);
|
||||||
}
|
}
|
||||||
|
|
@ -554,12 +562,14 @@ std::shared_ptr<linphone::ChatRoom> ToolModel::lookupChatForAddress(std::shared_
|
||||||
auto core = CoreModel::getInstance()->getCore();
|
auto core = CoreModel::getInstance()->getCore();
|
||||||
auto account = core->getDefaultAccount();
|
auto account = core->getDefaultAccount();
|
||||||
if (!account) return nullptr;
|
if (!account) return nullptr;
|
||||||
auto localAddress = account->getParams()->getIdentityAddress();
|
auto localAddress = account->getParams()->getIdentityAddress()->clone();
|
||||||
|
localAddress->clean();
|
||||||
if (!localAddress || !remoteAddress) return nullptr;
|
if (!localAddress || !remoteAddress) return nullptr;
|
||||||
|
|
||||||
auto params = getChatRoomParams(nullptr, remoteAddress);
|
auto params = getChatRoomParams(nullptr, remoteAddress);
|
||||||
std::list<std::shared_ptr<linphone::Address>> participants;
|
std::list<std::shared_ptr<linphone::Address>> participants;
|
||||||
participants.push_back(remoteAddress->clone());
|
remoteAddress->clean();
|
||||||
|
participants.push_back(remoteAddress);
|
||||||
|
|
||||||
qDebug() << "Looking for chat with local address" << localAddress->asStringUriOnly() << "and participant"
|
qDebug() << "Looking for chat with local address" << localAddress->asStringUriOnly() << "and participant"
|
||||||
<< remoteAddress->asStringUriOnly();
|
<< remoteAddress->asStringUriOnly();
|
||||||
|
|
@ -581,6 +591,33 @@ std::shared_ptr<linphone::ChatRoom> ToolModel::createChatForAddress(std::shared_
|
||||||
auto chatRoom = core->createChatRoom(params, participants);
|
auto chatRoom = core->createChatRoom(params, participants);
|
||||||
return chatRoom;
|
return chatRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<linphone::ChatRoom>
|
||||||
|
ToolModel::createGroupChatRoom(QString subject, std::list<std::shared_ptr<linphone::Address>> participantsAddresses) {
|
||||||
|
auto core = CoreModel::getInstance()->getCore();
|
||||||
|
auto account = core->getDefaultAccount();
|
||||||
|
|
||||||
|
auto params = core->createConferenceParams(nullptr);
|
||||||
|
params->enableChat(true);
|
||||||
|
params->enableGroup(true);
|
||||||
|
params->setSubject(Utils::appStringToCoreString(subject));
|
||||||
|
params->setAccount(account);
|
||||||
|
params->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd);
|
||||||
|
|
||||||
|
auto chatParams = params->getChatParams();
|
||||||
|
if (!chatParams) {
|
||||||
|
qWarning() << "failed to get chat params from conference params, return";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
chatParams->setEphemeralLifetime(0);
|
||||||
|
chatParams->setBackend(linphone::ChatRoom::Backend::FlexisipChat);
|
||||||
|
|
||||||
|
auto accountParams = account->getParams();
|
||||||
|
|
||||||
|
auto chatRoom = core->createChatRoom(params, participantsAddresses);
|
||||||
|
return chatRoom;
|
||||||
|
}
|
||||||
|
|
||||||
// Presence mapping from SDK PresenceModel/RFC 3863 <-> Linphone UI (5 statuses Online, Offline, Away, Busy, DND).
|
// Presence mapping from SDK PresenceModel/RFC 3863 <-> Linphone UI (5 statuses Online, Offline, Away, Busy, DND).
|
||||||
// Online = Basic Status open with no activity
|
// Online = Basic Status open with no activity
|
||||||
// Busy = Basic Status open with activity Busy and description busy
|
// Busy = Basic Status open with activity Busy and description busy
|
||||||
|
|
@ -589,11 +626,10 @@ std::shared_ptr<linphone::ChatRoom> ToolModel::createChatForAddress(std::shared_
|
||||||
// DND = Basic Status open with activity Other and description dnd
|
// DND = Basic Status open with activity Other and description dnd
|
||||||
// Note : close status on the last 2 items would be preferrable, but they currently trigger multiple tuple NOTIFY from
|
// Note : close status on the last 2 items would be preferrable, but they currently trigger multiple tuple NOTIFY from
|
||||||
// flexisip presence server Note 2 : close status with no activity triggers an unsubscribe.
|
// flexisip presence server Note 2 : close status with no activity triggers an unsubscribe.
|
||||||
|
|
||||||
LinphoneEnums::Presence
|
LinphoneEnums::Presence
|
||||||
ToolModel::corePresenceModelToAppPresence(std::shared_ptr<const linphone::PresenceModel> presenceModel) {
|
ToolModel::corePresenceModelToAppPresence(std::shared_ptr<const linphone::PresenceModel> presenceModel) {
|
||||||
if (!presenceModel) {
|
if (!presenceModel) {
|
||||||
lWarning() << sLog().arg("presence model is null.");
|
// lWarning() << sLog().arg("presence model is null.");
|
||||||
return LinphoneEnums::Presence::Undefined;
|
return LinphoneEnums::Presence::Undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,8 +85,11 @@ public:
|
||||||
getChatRoomParams(std::shared_ptr<linphone::Call> call, std::shared_ptr<linphone::Address> remoteAddress = nullptr);
|
getChatRoomParams(std::shared_ptr<linphone::Call> call, std::shared_ptr<linphone::Address> remoteAddress = nullptr);
|
||||||
static std::shared_ptr<linphone::ChatRoom> lookupCurrentCallChat(std::shared_ptr<CallModel> callModel);
|
static std::shared_ptr<linphone::ChatRoom> lookupCurrentCallChat(std::shared_ptr<CallModel> callModel);
|
||||||
static std::shared_ptr<linphone::ChatRoom> createCurrentCallChat(std::shared_ptr<CallModel> callModel);
|
static std::shared_ptr<linphone::ChatRoom> createCurrentCallChat(std::shared_ptr<CallModel> callModel);
|
||||||
|
static bool isEndToEndEncryptedChatAvailable();
|
||||||
static std::shared_ptr<linphone::ChatRoom> lookupChatForAddress(std::shared_ptr<linphone::Address> remoteAddress);
|
static std::shared_ptr<linphone::ChatRoom> lookupChatForAddress(std::shared_ptr<linphone::Address> remoteAddress);
|
||||||
static std::shared_ptr<linphone::ChatRoom> createChatForAddress(std::shared_ptr<linphone::Address> remoteAddress);
|
static std::shared_ptr<linphone::ChatRoom> createChatForAddress(std::shared_ptr<linphone::Address> remoteAddress);
|
||||||
|
static std::shared_ptr<linphone::ChatRoom>
|
||||||
|
createGroupChatRoom(QString subject, std::list<std::shared_ptr<linphone::Address>> participantsAddresses);
|
||||||
|
|
||||||
static LinphoneEnums::Presence
|
static LinphoneEnums::Presence
|
||||||
corePresenceModelToAppPresence(std::shared_ptr<const linphone::PresenceModel> presenceModel);
|
corePresenceModelToAppPresence(std::shared_ptr<const linphone::PresenceModel> presenceModel);
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ public:
|
||||||
Q_PROPERTY(QString ContactUrl MEMBER ContactUrl CONSTANT)
|
Q_PROPERTY(QString ContactUrl MEMBER ContactUrl CONSTANT)
|
||||||
Q_PROPERTY(QString TranslationUrl MEMBER TranslationUrl CONSTANT)
|
Q_PROPERTY(QString TranslationUrl MEMBER TranslationUrl CONSTANT)
|
||||||
Q_PROPERTY(QString DefaultFont MEMBER DefaultFont CONSTANT)
|
Q_PROPERTY(QString DefaultFont MEMBER DefaultFont CONSTANT)
|
||||||
|
Q_PROPERTY(QString DefaultLocale MEMBER DefaultLocale CONSTANT)
|
||||||
Q_PROPERTY(int maxMosaicParticipants MEMBER MaxMosaicParticipants CONSTANT)
|
Q_PROPERTY(int maxMosaicParticipants MEMBER MaxMosaicParticipants CONSTANT)
|
||||||
Q_PROPERTY(QStringList reactionsList READ getReactionsList CONSTANT)
|
Q_PROPERTY(QStringList reactionsList READ getReactionsList CONSTANT)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1538,7 +1538,7 @@ VariantObject *Utils::getCurrentCallChat(CallGui *call) {
|
||||||
data->mConnection->invokeToCore([] {
|
data->mConnection->invokeToCore([] {
|
||||||
//: Error
|
//: Error
|
||||||
showInformationPopup(tr("information_popup_error_title"),
|
showInformationPopup(tr("information_popup_error_title"),
|
||||||
//: Failed to create 1-1 conversation with %1 !
|
//: Failed to create 1-1 conversation with %1 !
|
||||||
tr("information_popup_chatroom_creation_error_message"), false,
|
tr("information_popup_chatroom_creation_error_message"), false,
|
||||||
getCallsWindow());
|
getCallsWindow());
|
||||||
});
|
});
|
||||||
|
|
@ -1556,6 +1556,7 @@ VariantObject *Utils::getChatForAddress(QString address) {
|
||||||
data->makeRequest([address, data]() {
|
data->makeRequest([address, data]() {
|
||||||
auto linAddr = ToolModel::interpretUrl(address);
|
auto linAddr = ToolModel::interpretUrl(address);
|
||||||
if (!linAddr) return QVariant();
|
if (!linAddr) return QVariant();
|
||||||
|
linAddr->clean();
|
||||||
auto linphoneChatRoom = ToolModel::lookupChatForAddress(linAddr);
|
auto linphoneChatRoom = ToolModel::lookupChatForAddress(linAddr);
|
||||||
if (linphoneChatRoom) {
|
if (linphoneChatRoom) {
|
||||||
auto chatCore = ChatCore::create(linphoneChatRoom);
|
auto chatCore = ChatCore::create(linphoneChatRoom);
|
||||||
|
|
@ -1584,6 +1585,28 @@ VariantObject *Utils::getChatForAddress(QString address) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VariantObject *Utils::createGroupChat(QString subject, QStringList participantAddresses) {
|
||||||
|
VariantObject *data = new VariantObject("lookupCurrentCallChat");
|
||||||
|
if (!data) return nullptr;
|
||||||
|
data->makeRequest([subject, participantAddresses, data]() {
|
||||||
|
std::list<std::shared_ptr<linphone::Address>> addresses;
|
||||||
|
for (auto &addr : participantAddresses) {
|
||||||
|
auto linAddr = ToolModel::interpretUrl(addr);
|
||||||
|
if (linAddr) addresses.push_back(linAddr);
|
||||||
|
else lWarning() << "Could not interpret address" << addr;
|
||||||
|
}
|
||||||
|
auto linphoneChatRoom = ToolModel::createGroupChatRoom(subject, addresses);
|
||||||
|
if (linphoneChatRoom) {
|
||||||
|
auto chatCore = ChatCore::create(linphoneChatRoom);
|
||||||
|
return QVariant::fromValue(new ChatGui(chatCore));
|
||||||
|
} else {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
data->requestValue();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
void Utils::openChat(ChatGui *chat) {
|
void Utils::openChat(ChatGui *chat) {
|
||||||
auto mainWindow = getMainWindow();
|
auto mainWindow = getMainWindow();
|
||||||
smartShowWindow(mainWindow);
|
smartShowWindow(mainWindow);
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,7 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE static VariantObject *getCurrentCallChat(CallGui *call);
|
Q_INVOKABLE static VariantObject *getCurrentCallChat(CallGui *call);
|
||||||
Q_INVOKABLE static VariantObject *getChatForAddress(QString address);
|
Q_INVOKABLE static VariantObject *getChatForAddress(QString address);
|
||||||
|
Q_INVOKABLE static VariantObject *createGroupChat(QString subject, QStringList participantAddresses);
|
||||||
Q_INVOKABLE static void openChat(ChatGui *chat);
|
Q_INVOKABLE static void openChat(ChatGui *chat);
|
||||||
Q_INVOKABLE static bool isEmptyMessage(QString message);
|
Q_INVOKABLE static bool isEmptyMessage(QString message);
|
||||||
Q_INVOKABLE static QString encodeTextToQmlRichFormat(const QString &text,
|
Q_INVOKABLE static QString encodeTextToQmlRichFormat(const QString &text,
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
||||||
view/Control/Button/Settings/SwitchSetting.qml
|
view/Control/Button/Settings/SwitchSetting.qml
|
||||||
|
|
||||||
view/Control/Container/Carousel.qml
|
view/Control/Container/Carousel.qml
|
||||||
|
view/Control/Container/CreationFormLayout.qml
|
||||||
|
view/Control/Container/GroupCreationFormLayout.qml
|
||||||
view/Control/Container/DetailLayout.qml
|
view/Control/Container/DetailLayout.qml
|
||||||
view/Control/Container/FormItemLayout.qml
|
view/Control/Container/FormItemLayout.qml
|
||||||
view/Control/Container/ScrollBar.qml
|
view/Control/Container/ScrollBar.qml
|
||||||
|
|
@ -107,6 +109,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
||||||
view/Control/Tool/Prototype/PhoneNumberPrototype.qml
|
view/Control/Tool/Prototype/PhoneNumberPrototype.qml
|
||||||
|
|
||||||
view/Page/Form/Call/NewCallForm.qml
|
view/Page/Form/Call/NewCallForm.qml
|
||||||
|
view/Page/Form/Chat/NewChatForm.qml
|
||||||
view/Page/Form/Chat/SelectedChatView.qml
|
view/Page/Form/Chat/SelectedChatView.qml
|
||||||
view/Page/Form/Contact/ContactDescription.qml
|
view/Page/Form/Contact/ContactDescription.qml
|
||||||
view/Page/Form/Contact/ContactEdition.qml
|
view/Page/Form/Contact/ContactEdition.qml
|
||||||
|
|
|
||||||
109
Linphone/view/Control/Container/CreationFormLayout.qml
Normal file
109
Linphone/view/Control/Container/CreationFormLayout.qml
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls.Basic as Control
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp
|
||||||
|
import SettingsCpp
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
id: mainItem
|
||||||
|
property color searchBarColor: DefaultStyle.grey_100
|
||||||
|
property color searchBarBorderColor: "transparent"
|
||||||
|
property alias searchBar: searchBar
|
||||||
|
property string startGroupButtonText
|
||||||
|
property NumericPadPopup numPadPopup
|
||||||
|
signal groupCreationRequested()
|
||||||
|
signal contactClicked(FriendGui contact)
|
||||||
|
clip: true
|
||||||
|
property alias topContent: topLayout.data
|
||||||
|
property bool topLayoutVisible: topLayout.children.length > 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: Math.round(22 * DefaultStyle.dp)
|
||||||
|
ColumnLayout {
|
||||||
|
id: topLayout
|
||||||
|
visible: mainItem.topLayoutVisible
|
||||||
|
spacing: Math.round(18 * DefaultStyle.dp)
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
onVisibleChanged: if (!visible && mainItem.numPadPopup) mainItem.numPadPopup.close()
|
||||||
|
spacing: Math.round(38 * DefaultStyle.dp)
|
||||||
|
SearchBar {
|
||||||
|
id: searchBar
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.rightMargin: Math.round(39 * DefaultStyle.dp)
|
||||||
|
focus: true
|
||||||
|
color: mainItem.searchBarColor
|
||||||
|
borderColor: mainItem.searchBarBorderColor
|
||||||
|
//: "Rechercher un contact"
|
||||||
|
placeholderText: qsTr("search_bar_look_for_contact_text")
|
||||||
|
numericPadPopup: mainItem.numPadPopup
|
||||||
|
KeyNavigation.down: grouCreationButton
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
spacing: Math.round(32 * DefaultStyle.dp)
|
||||||
|
Button {
|
||||||
|
id: grouCreationButton
|
||||||
|
Layout.preferredWidth: Math.round(320 * DefaultStyle.dp)
|
||||||
|
Layout.preferredHeight: Math.round(44 * DefaultStyle.dp)
|
||||||
|
padding: 0
|
||||||
|
KeyNavigation.up: searchBar
|
||||||
|
KeyNavigation.down: contactList
|
||||||
|
onClicked: mainItem.groupCreationRequested()
|
||||||
|
background: Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Math.round(50 * DefaultStyle.dp)
|
||||||
|
gradient: Gradient {
|
||||||
|
orientation: Gradient.Horizontal
|
||||||
|
GradientStop { position: 0.0; color: DefaultStyle.main2_100}
|
||||||
|
GradientStop { position: 1.0; color: DefaultStyle.grey_0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: Math.round(16 * DefaultStyle.dp)
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
Image {
|
||||||
|
source: AppIcons.groupCall
|
||||||
|
Layout.preferredWidth: Math.round(44 * DefaultStyle.dp)
|
||||||
|
sourceSize.width: Math.round(44 * DefaultStyle.dp)
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: mainItem.startGroupButtonText
|
||||||
|
color: DefaultStyle.grey_1000
|
||||||
|
font {
|
||||||
|
pixelSize: Typography.h4.pixelSize
|
||||||
|
weight: Typography.h4.weight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
EffectImage {
|
||||||
|
imageSource: AppIcons.rightArrow
|
||||||
|
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
|
||||||
|
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
|
||||||
|
colorizationColor: DefaultStyle.main2_500main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AllContactListView{
|
||||||
|
id: contactList
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
showContactMenu: false
|
||||||
|
searchBarText: searchBar.text
|
||||||
|
onContactSelected: (contact) => {
|
||||||
|
mainItem.contactClicked(contact)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
101
Linphone/view/Control/Container/GroupCreationFormLayout.qml
Normal file
101
Linphone/view/Control/Container/GroupCreationFormLayout.qml
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls.Basic as Control
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp
|
||||||
|
import SettingsCpp
|
||||||
|
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
id: mainItem
|
||||||
|
property alias addParticipantsLayout: addParticipantsLayout
|
||||||
|
property alias groupName: groupName
|
||||||
|
property string formTitle
|
||||||
|
property string createGroupButtonText
|
||||||
|
property int selectedParticipantsCount
|
||||||
|
signal returnRequested()
|
||||||
|
signal groupCreationRequested()
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
anchors.fill: parent
|
||||||
|
RowLayout {
|
||||||
|
spacing: Math.round(10 * DefaultStyle.dp)
|
||||||
|
Button {
|
||||||
|
id: backGroupCallButton
|
||||||
|
style: ButtonStyle.noBackgroundOrange
|
||||||
|
icon.source: AppIcons.leftArrow
|
||||||
|
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
|
||||||
|
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
|
||||||
|
KeyNavigation.down: groupName
|
||||||
|
KeyNavigation.right: groupCallButton
|
||||||
|
KeyNavigation.left: groupCallButton
|
||||||
|
onClicked: {
|
||||||
|
mainItem.returnRequested()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: mainItem.formTitle
|
||||||
|
color: DefaultStyle.main1_500_main
|
||||||
|
maximumLineCount: 1
|
||||||
|
font {
|
||||||
|
pixelSize: Math.round(18 * DefaultStyle.dp)
|
||||||
|
weight: Typography.h4.weight
|
||||||
|
}
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
SmallButton {
|
||||||
|
id: groupCallButton
|
||||||
|
enabled: mainItem.selectedParticipantsCount.length != 0
|
||||||
|
Layout.rightMargin: Math.round(21 * DefaultStyle.dp)
|
||||||
|
text: mainItem.createGroupButtonText
|
||||||
|
style: ButtonStyle.main
|
||||||
|
KeyNavigation.down: addParticipantsLayout
|
||||||
|
KeyNavigation.left: backGroupCallButton
|
||||||
|
KeyNavigation.right: backGroupCallButton
|
||||||
|
onClicked: {
|
||||||
|
mainItem.groupCreationRequested()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
spacing: 0
|
||||||
|
Layout.topMargin: Math.round(18 * DefaultStyle.dp)
|
||||||
|
Layout.rightMargin: Math.round(38 * DefaultStyle.dp)
|
||||||
|
Text {
|
||||||
|
font.pixelSize: Typography.p2.pixelSize
|
||||||
|
font.weight: Typography.p2.weight
|
||||||
|
//: "Nom du groupe"
|
||||||
|
text: qsTr("history_group_call_start_dialog_subject_hint")
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
font.pixelSize: Math.round(12 * DefaultStyle.dp)
|
||||||
|
font.weight: Math.round(300 * DefaultStyle.dp)
|
||||||
|
//: "Requis"
|
||||||
|
text: qsTr("required")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: groupName
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.rightMargin: Math.round(38 * DefaultStyle.dp)
|
||||||
|
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp)
|
||||||
|
focus: true
|
||||||
|
KeyNavigation.down: addParticipantsLayout //participantList.count > 0 ? participantList : searchbar
|
||||||
|
}
|
||||||
|
AddParticipantsForm {
|
||||||
|
id: addParticipantsLayout
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.topMargin: Math.round(15 * DefaultStyle.dp)
|
||||||
|
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,9 @@ ListView {
|
||||||
property string searchText: searchBar?.text
|
property string searchText: searchBar?.text
|
||||||
property real busyIndicatorSize: Math.round(60 * DefaultStyle.dp)
|
property real busyIndicatorSize: Math.round(60 * DefaultStyle.dp)
|
||||||
|
|
||||||
|
property ChatGui currentChatGui
|
||||||
|
onCurrentIndexChanged: currentChatGui = model.getAt(currentIndex) || null
|
||||||
|
|
||||||
signal resultsReceived
|
signal resultsReceived
|
||||||
|
|
||||||
onResultsReceived: {
|
onResultsReceived: {
|
||||||
|
|
@ -43,6 +46,10 @@ ListView {
|
||||||
mainItem.currentIndex = -1
|
mainItem.currentIndex = -1
|
||||||
mainItem.currentIndex = indexToSelect
|
mainItem.currentIndex = indexToSelect
|
||||||
}
|
}
|
||||||
|
onLayoutChanged: {
|
||||||
|
var chatToSelect = getAt(mainItem.currentIndex)
|
||||||
|
selectChat(mainItem.currentChatGui)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// flickDeceleration: 10000
|
// flickDeceleration: 10000
|
||||||
spacing: Math.round(10 * DefaultStyle.dp)
|
spacing: Math.round(10 * DefaultStyle.dp)
|
||||||
|
|
@ -50,6 +57,14 @@ ListView {
|
||||||
function selectChat(chatGui) {
|
function selectChat(chatGui) {
|
||||||
var index = chatProxy.findChatIndex(chatGui)
|
var index = chatProxy.findChatIndex(chatGui)
|
||||||
mainItem.currentIndex = index
|
mainItem.currentIndex = index
|
||||||
|
// if the chat exists, it may not be displayed
|
||||||
|
// in list if hide_empty_chatrooms is set. Thus, we need
|
||||||
|
// to force adding it in the list so it is displayed
|
||||||
|
if (index === -1 && chatGui) {
|
||||||
|
chatProxy.addChatInList(chatGui)
|
||||||
|
var index = chatProxy.findChatIndex(chatGui)
|
||||||
|
mainItem.currentIndex = index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: cacheBuffer = Math.max(contentHeight, 0) //contentHeight>0 ? contentHeight : 0// cache all items
|
Component.onCompleted: cacheBuffer = Math.max(contentHeight, 0) //contentHeight>0 ? contentHeight : 0// cache all items
|
||||||
|
|
@ -67,9 +82,6 @@ ListView {
|
||||||
chatProxy.displayMore()
|
chatProxy.displayMore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onCountChanged: {
|
|
||||||
if (count > 0 && currentIndex < 0) currentIndex = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
function moveToCurrentItem() {
|
function moveToCurrentItem() {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import QtQuick.Controls.Basic as Control
|
||||||
|
|
||||||
import Linphone
|
import Linphone
|
||||||
import UtilsCpp 1.0
|
import UtilsCpp 1.0
|
||||||
import ConstantsCpp 1.0
|
import ConstantsCpp
|
||||||
import SettingsCpp
|
import SettingsCpp
|
||||||
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
|
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ Notification {
|
||||||
property string message: notificationData ? notificationData.message : ""
|
property string message: notificationData ? notificationData.message : ""
|
||||||
Connections {
|
Connections {
|
||||||
enabled: chat
|
enabled: chat
|
||||||
target: chat.core
|
target: chat ? chat.core : null
|
||||||
function onMessageOpen() {
|
function onMessageOpen() {
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,131 +7,43 @@ import Linphone
|
||||||
import UtilsCpp
|
import UtilsCpp
|
||||||
import SettingsCpp
|
import SettingsCpp
|
||||||
|
|
||||||
FocusScope {
|
CreationFormLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
property bool groupCallVisible
|
property bool groupCallVisible
|
||||||
property bool displayCurrentCalls: false
|
property bool displayCurrentCalls: false
|
||||||
property color searchBarColor: DefaultStyle.grey_100
|
|
||||||
property color searchBarBorderColor: "transparent"
|
|
||||||
property alias searchBar: searchBar
|
|
||||||
property NumericPadPopup numPadPopup
|
|
||||||
signal callButtonPressed(string address)
|
|
||||||
signal groupCallCreationRequested()
|
|
||||||
signal transferCallToAnotherRequested(CallGui dest)
|
signal transferCallToAnotherRequested(CallGui dest)
|
||||||
signal contactClicked(FriendGui contact)
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
ColumnLayout {
|
//: Appel de groupe
|
||||||
anchors.fill: parent
|
startGroupButtonText: qsTr("call_start_group_call_title")
|
||||||
spacing: Math.round(22 * DefaultStyle.dp)
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Math.round(18 * DefaultStyle.dp)
|
|
||||||
visible: mainItem.displayCurrentCalls && callList.count > 0
|
|
||||||
Text {
|
|
||||||
//: "Appels en cours"
|
|
||||||
text: qsTr("call_transfer_active_calls_label")
|
|
||||||
font {
|
|
||||||
pixelSize: Typography.h4.pixelSize
|
|
||||||
weight: Typography.h4.weight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Flickable {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: callListBackground.height
|
|
||||||
Layout.maximumHeight: mainItem.height/2
|
|
||||||
contentHeight: callListBackground.height
|
|
||||||
contentWidth: width
|
|
||||||
RoundedPane {
|
|
||||||
id: callListBackground
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
contentItem: CallListView {
|
|
||||||
id: callList
|
|
||||||
isTransferList: true
|
|
||||||
onTransferCallToAnotherRequested: (dest) => {
|
|
||||||
mainItem.transferCallToAnotherRequested(dest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
topLayoutVisible: mainItem.displayCurrentCalls && callList.count > 0
|
||||||
onVisibleChanged: if (!visible) mainItem.numPadPopup.close()
|
topContent: [
|
||||||
spacing: Math.round(38 * DefaultStyle.dp)
|
Text {
|
||||||
SearchBar {
|
//: "Appels en cours"
|
||||||
id: searchBar
|
text: qsTr("call_transfer_active_calls_label")
|
||||||
Layout.alignment: Qt.AlignTop
|
font {
|
||||||
Layout.fillWidth: true
|
pixelSize: Typography.h4.pixelSize
|
||||||
Layout.rightMargin: Math.round(39 * DefaultStyle.dp)
|
weight: Typography.h4.weight
|
||||||
focus: true
|
|
||||||
color: mainItem.searchBarColor
|
|
||||||
borderColor: mainItem.searchBarBorderColor
|
|
||||||
//: "Rechercher un contact"
|
|
||||||
placeholderText: qsTr("search_bar_look_for_contact_text")
|
|
||||||
numericPadPopup: mainItem.numPadPopup
|
|
||||||
KeyNavigation.down: grouCallButton
|
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
},
|
||||||
id: content
|
Flickable {
|
||||||
spacing: Math.round(32 * DefaultStyle.dp)
|
Layout.fillWidth: true
|
||||||
Button {
|
Layout.preferredHeight: callListBackground.height
|
||||||
id: grouCallButton
|
Layout.maximumHeight: mainItem.height/2
|
||||||
visible: mainItem.groupCallVisible && !SettingsCpp.disableMeetingsFeature
|
contentHeight: callListBackground.height
|
||||||
Layout.preferredWidth: Math.round(320 * DefaultStyle.dp)
|
contentWidth: width
|
||||||
Layout.preferredHeight: Math.round(44 * DefaultStyle.dp)
|
RoundedPane {
|
||||||
padding: 0
|
id: callListBackground
|
||||||
KeyNavigation.up: searchBar
|
anchors.left: parent.left
|
||||||
KeyNavigation.down: contactList
|
anchors.right: parent.right
|
||||||
onClicked: mainItem.groupCallCreationRequested()
|
contentItem: CallListView {
|
||||||
background: Rectangle {
|
id: callList
|
||||||
anchors.fill: parent
|
isTransferList: true
|
||||||
radius: Math.round(50 * DefaultStyle.dp)
|
onTransferCallToAnotherRequested: (dest) => {
|
||||||
gradient: Gradient {
|
mainItem.transferCallToAnotherRequested(dest)
|
||||||
orientation: Gradient.Horizontal
|
|
||||||
GradientStop { position: 0.0; color: DefaultStyle.main2_100}
|
|
||||||
GradientStop { position: 1.0; color: DefaultStyle.grey_0}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
contentItem: RowLayout {
|
|
||||||
spacing: Math.round(16 * DefaultStyle.dp)
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
Image {
|
|
||||||
source: AppIcons.groupCall
|
|
||||||
Layout.preferredWidth: Math.round(44 * DefaultStyle.dp)
|
|
||||||
sourceSize.width: Math.round(44 * DefaultStyle.dp)
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: qsTr("call_start_group_call_title")
|
|
||||||
color: DefaultStyle.grey_1000
|
|
||||||
font {
|
|
||||||
pixelSize: Typography.h4.pixelSize
|
|
||||||
weight: Typography.h4.weight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
EffectImage {
|
|
||||||
imageSource: AppIcons.rightArrow
|
|
||||||
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
|
|
||||||
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
|
|
||||||
colorizationColor: DefaultStyle.main2_500main
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AllContactListView{
|
|
||||||
id: contactList
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
showContactMenu: false
|
|
||||||
searchBarText: searchBar.text
|
|
||||||
onContactSelected: (contact) => {
|
|
||||||
mainItem.contactClicked(contact)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
Linphone/view/Page/Form/Chat/GroupChatForm.qml
Normal file
15
Linphone/view/Page/Form/Chat/GroupChatForm.qml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls.Basic as Control
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp
|
||||||
|
import SettingsCpp
|
||||||
|
|
||||||
|
CreationFormLayout {
|
||||||
|
id: mainItem
|
||||||
|
|
||||||
|
//: Nouveau groupe
|
||||||
|
startGroupButtonText: qsTr("chat_start_group_chat_title")
|
||||||
|
}
|
||||||
15
Linphone/view/Page/Form/Chat/NewChatForm.qml
Normal file
15
Linphone/view/Page/Form/Chat/NewChatForm.qml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls.Basic as Control
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp
|
||||||
|
import SettingsCpp
|
||||||
|
|
||||||
|
CreationFormLayout {
|
||||||
|
id: mainItem
|
||||||
|
|
||||||
|
//: Nouveau groupe
|
||||||
|
startGroupButtonText: qsTr("chat_start_group_chat_title")
|
||||||
|
}
|
||||||
|
|
@ -25,52 +25,94 @@ FocusScope{
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: Math.round(15 * DefaultStyle.dp)
|
spacing: Math.round(15 * DefaultStyle.dp)
|
||||||
ListView {
|
GridView {
|
||||||
id: participantList
|
id: participantList
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
visible: contentHeight > 0
|
visible: contentHeight > 0
|
||||||
Layout.preferredHeight: contentHeight
|
Layout.preferredHeight: contentHeight
|
||||||
Layout.maximumHeight: mainItem.height / 3
|
Layout.maximumHeight: mainItem.height / 3
|
||||||
width: mainItem.width
|
width: mainItem.width
|
||||||
|
cellWidth: Math.round((50 + 18) * DefaultStyle.dp)
|
||||||
|
cellHeight: Math.round(80 * DefaultStyle.dp)
|
||||||
|
// columnCount: Math.floor(width/cellWidth)
|
||||||
model: mainItem.selectedParticipants
|
model: mainItem.selectedParticipants
|
||||||
clip: true
|
clip: true
|
||||||
|
// columnSpacing: Math.round(18 * DefaultStyle.dp)
|
||||||
|
// rowSpacing: Math.round(9 * DefaultStyle.dp)
|
||||||
Keys.onPressed: (event) => {
|
Keys.onPressed: (event) => {
|
||||||
if(currentIndex <=0 && event.key == Qt.Key_Up){
|
if(currentIndex <=0 && event.key == Qt.Key_Up){
|
||||||
nextItemInFocusChain(false).forceActiveFocus()
|
nextItemInFocusChain(false).forceActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
header: Text {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
visible: count > 0
|
||||||
|
//: "%n participant(s) sélectionné(s)"
|
||||||
|
text: qsTr("add_participant_selected_count", '', count).arg(count)
|
||||||
|
maximumLineCount: 1
|
||||||
|
color: DefaultStyle.grey_1000
|
||||||
|
font {
|
||||||
|
pixelSize: Math.round(12 * DefaultStyle.dp)
|
||||||
|
weight: Math.round(300 * DefaultStyle.dp)
|
||||||
|
}
|
||||||
|
}
|
||||||
delegate: FocusScope {
|
delegate: FocusScope {
|
||||||
height: Math.round(56 * DefaultStyle.dp)
|
ColumnLayout {
|
||||||
width: participantList.width - scrollbar.implicitWidth - Math.round(28 * DefaultStyle.dp)
|
|
||||||
RowLayout {
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: Math.round(10 * DefaultStyle.dp)
|
spacing: Math.round(4 * DefaultStyle.dp)
|
||||||
Avatar {
|
width: Math.round(50 * DefaultStyle.dp)
|
||||||
Layout.preferredWidth: Math.round(45 * DefaultStyle.dp)
|
Item {
|
||||||
Layout.preferredHeight: Math.round(45 * DefaultStyle.dp)
|
Layout.alignment: Qt.AlignHCenter
|
||||||
_address: modelData
|
Layout.preferredWidth: Math.round(50 * DefaultStyle.dp)
|
||||||
shadowEnabled: false
|
Layout.preferredHeight: Math.round(50 * DefaultStyle.dp)
|
||||||
|
Avatar {
|
||||||
|
anchors.fill: parent
|
||||||
|
_address: modelData
|
||||||
|
shadowEnabled: false
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.preferredWidth: Math.round(17 * DefaultStyle.dp)
|
||||||
|
Layout.preferredHeight: Math.round(17 * DefaultStyle.dp)
|
||||||
|
icon.width: Math.round(12 * DefaultStyle.dp)
|
||||||
|
icon.height: Math.round(12 * DefaultStyle.dp)
|
||||||
|
icon.source: AppIcons.closeX
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
background: Item {
|
||||||
|
Rectangle {
|
||||||
|
id: backgroundRect
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Math.round(50 * DefaultStyle.dp)
|
||||||
|
}
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: backgroundRect
|
||||||
|
source: backgroundRect
|
||||||
|
shadowEnabled: true
|
||||||
|
shadowColor: DefaultStyle.grey_1000
|
||||||
|
shadowBlur: 0.1
|
||||||
|
shadowOpacity: 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: contactList.removeSelectedContactByAddress(modelData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
Layout.fillWidth: true
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.preferredWidth: width
|
||||||
|
width: Math.round(50 * DefaultStyle.dp)
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
|
clip: true
|
||||||
property var nameObj: UtilsCpp.getDisplayName(modelData)
|
property var nameObj: UtilsCpp.getDisplayName(modelData)
|
||||||
text: nameObj ? nameObj.value : ""
|
text: nameObj ? nameObj.value : ""
|
||||||
font.pixelSize: Math.round(14 * DefaultStyle.dp)
|
color: DefaultStyle.main2_700
|
||||||
font.capitalization: Font.Capitalize
|
wrapMode: Text.WrapAnywhere
|
||||||
}
|
font {
|
||||||
Item {
|
pixelSize: Typography.p3.pixelSize
|
||||||
Layout.fillWidth: true
|
weight: Typography.p3.weight
|
||||||
}
|
capitalization: Font.Capitalize
|
||||||
Button {
|
}
|
||||||
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
|
|
||||||
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
|
|
||||||
style: ButtonStyle.noBackgroundOrange
|
|
||||||
icon.source: AppIcons.closeX
|
|
||||||
icon.width: Math.round(24 * DefaultStyle.dp)
|
|
||||||
icon.height: Math.round(24 * DefaultStyle.dp)
|
|
||||||
focus: true
|
|
||||||
onClicked: contactList.removeSelectedContactByAddress(modelData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ AbstractMainPage {
|
||||||
property bool isRegistered: account ? account.core?.registrationState
|
property bool isRegistered: account ? account.core?.registrationState
|
||||||
== LinphoneEnums.RegistrationState.Ok : false
|
== LinphoneEnums.RegistrationState.Ok : false
|
||||||
property int selectedParticipantsCount
|
property int selectedParticipantsCount
|
||||||
signal startGroupCallRequested
|
|
||||||
signal createCallFromSearchBarRequested
|
signal createCallFromSearchBarRequested
|
||||||
signal createContactRequested(string name, string address)
|
signal createContactRequested(string name, string address)
|
||||||
signal openNumPadRequest
|
signal openNumPadRequest
|
||||||
|
|
@ -370,7 +369,7 @@ AbstractMainPage {
|
||||||
onContactClicked: contact => {
|
onContactClicked: contact => {
|
||||||
mainWindow.startCallWithContact(contact, false, callContactsList)
|
mainWindow.startCallWithContact(contact, false, callContactsList)
|
||||||
}
|
}
|
||||||
onGroupCallCreationRequested: {
|
onGroupCreationRequested: {
|
||||||
console.log("groupe call requetsed")
|
console.log("groupe call requetsed")
|
||||||
listStackView.push(groupCallItem)
|
listStackView.push(groupCallItem)
|
||||||
}
|
}
|
||||||
|
|
@ -387,129 +386,30 @@ AbstractMainPage {
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: groupCallItem
|
id: groupCallItem
|
||||||
FocusScope {
|
GroupCreationFormLayout {
|
||||||
objectName: "groupCallItem"
|
objectName: "groupCallItem"
|
||||||
|
//: "Appel de groupe"
|
||||||
|
formTitle: qsTr("call_start_group_call_title")
|
||||||
|
//: "Lancer"
|
||||||
|
createGroupButtonText: qsTr("call_action_start_group_call")
|
||||||
Control.StackView.onActivated: {
|
Control.StackView.onActivated: {
|
||||||
addParticipantsLayout.forceActiveFocus()
|
addParticipantsLayout.forceActiveFocus()
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
onReturnRequested: {
|
||||||
spacing: 0
|
listStackView.pop()
|
||||||
anchors.fill: parent
|
listStackView.currentItem?.forceActiveFocus()
|
||||||
RowLayout {
|
}
|
||||||
spacing: Math.round(10 * DefaultStyle.dp)
|
onGroupCreationRequested: {
|
||||||
visible: !SettingsCpp.disableMeetingsFeature
|
if (groupName.text.length === 0) {
|
||||||
Button {
|
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
|
||||||
id: backGroupCallButton
|
//: "Un nom doit être donné à l'appel de groupe
|
||||||
style: ButtonStyle.noBackgroundOrange
|
qsTr("group_call_error_must_have_name"), false)
|
||||||
icon.source: AppIcons.leftArrow
|
} else if (!mainItem.isRegistered) {
|
||||||
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
|
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
|
||||||
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
|
//: "Vous n'etes pas connecté"
|
||||||
KeyNavigation.down: listStackView
|
qsTr("group_call_error_not_connected"), false)
|
||||||
KeyNavigation.right: groupCallButton
|
} else {
|
||||||
KeyNavigation.left: groupCallButton
|
UtilsCpp.createGroupCall(groupName.text, addParticipantsLayout.selectedParticipants)
|
||||||
onClicked: {
|
|
||||||
listStackView.pop()
|
|
||||||
listStackView.currentItem?.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ColumnLayout {
|
|
||||||
spacing: Math.round(3 * DefaultStyle.dp)
|
|
||||||
Text {
|
|
||||||
//: "Appel de groupe"
|
|
||||||
text: qsTr("call_start_group_call_title")
|
|
||||||
color: DefaultStyle.main1_500_main
|
|
||||||
maximumLineCount: 1
|
|
||||||
font {
|
|
||||||
pixelSize: Math.round(18 * DefaultStyle.dp)
|
|
||||||
weight: Typography.h4.weight
|
|
||||||
}
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
//: "%n participant(s) sélectionné(s)"
|
|
||||||
text: qsTr("group_call_participant_selected", '', mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount)
|
|
||||||
color: DefaultStyle.main2_500main
|
|
||||||
maximumLineCount: 1
|
|
||||||
font {
|
|
||||||
pixelSize: Math.round(12 * DefaultStyle.dp)
|
|
||||||
weight: Math.round(300 * DefaultStyle.dp)
|
|
||||||
}
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SmallButton {
|
|
||||||
id: groupCallButton
|
|
||||||
enabled: mainItem.selectedParticipantsCount.length != 0
|
|
||||||
Layout.rightMargin: Math.round(21 * DefaultStyle.dp)
|
|
||||||
//: "Lancer"
|
|
||||||
text: qsTr("call_action_start_group_call")
|
|
||||||
style: ButtonStyle.main
|
|
||||||
KeyNavigation.down: listStackView
|
|
||||||
KeyNavigation.left: backGroupCallButton
|
|
||||||
KeyNavigation.right: backGroupCallButton
|
|
||||||
onClicked: {
|
|
||||||
mainItem.startGroupCallRequested()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RowLayout {
|
|
||||||
spacing: 0
|
|
||||||
Layout.topMargin: Math.round(18 * DefaultStyle.dp)
|
|
||||||
Layout.rightMargin: Math.round(38 * DefaultStyle.dp)
|
|
||||||
Text {
|
|
||||||
font.pixelSize: Typography.p2.pixelSize
|
|
||||||
font.weight: Typography.p2.weight
|
|
||||||
//: "Nom du groupe"
|
|
||||||
text: qsTr("history_group_call_start_dialog_subject_hint")
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
font.pixelSize: Math.round(12 * DefaultStyle.dp)
|
|
||||||
font.weight: Math.round(300 * DefaultStyle.dp)
|
|
||||||
//: "Requis"
|
|
||||||
text: qsTr("required")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TextField {
|
|
||||||
id: groupCallName
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.rightMargin: Math.round(38 * DefaultStyle.dp)
|
|
||||||
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp)
|
|
||||||
focus: true
|
|
||||||
KeyNavigation.down: addParticipantsLayout //participantList.count > 0 ? participantList : searchbar
|
|
||||||
}
|
|
||||||
AddParticipantsForm {
|
|
||||||
id: addParticipantsLayout
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.topMargin: Math.round(15 * DefaultStyle.dp)
|
|
||||||
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
|
|
||||||
focus: true
|
|
||||||
Connections {
|
|
||||||
target: mainItem
|
|
||||||
function onStartGroupCallRequested() {
|
|
||||||
if (groupCallName.text.length === 0) {
|
|
||||||
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
|
|
||||||
//: "Un nom doit être donné à l'appel de groupe
|
|
||||||
qsTr("group_call_error_must_have_name"), false)
|
|
||||||
} else if (!mainItem.isRegistered) {
|
|
||||||
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
|
|
||||||
//: "Vous n'etes pas connecté"
|
|
||||||
qsTr("group_call_error_not_connected"), false)
|
|
||||||
} else {
|
|
||||||
// mainItem.confInfoGui = Qt.createQmlObject(
|
|
||||||
// "import Linphone
|
|
||||||
// ConferenceInfoGui{}", mainItem)
|
|
||||||
// mainItem.confInfoGui.core.subject = groupCallName.text
|
|
||||||
// mainItem.confInfoGui.core.isScheduled = false
|
|
||||||
// mainItem.confInfoGui.core.addParticipants(addParticipantsLayout.selectedParticipants)
|
|
||||||
// mainItem.confInfoGui.core.save()
|
|
||||||
UtilsCpp.createGroupCall(groupCallName.text, addParticipantsLayout.selectedParticipants)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,24 +16,41 @@ AbstractMainPage {
|
||||||
emptyListText: qsTr("chat_empty_title")
|
emptyListText: qsTr("chat_empty_title")
|
||||||
newItemIconSource: AppIcons.plusCircle
|
newItemIconSource: AppIcons.plusCircle
|
||||||
|
|
||||||
property var selectedChatGui
|
property AccountProxy accounts: AccountProxy {
|
||||||
|
id: accountProxy
|
||||||
|
sourceModel: AppCpp.accounts
|
||||||
|
}
|
||||||
|
property AccountGui account: accountProxy.defaultAccount
|
||||||
|
property var state: account && account.core?.registrationState || 0
|
||||||
|
property bool isRegistered: account ? account.core?.registrationState
|
||||||
|
== LinphoneEnums.RegistrationState.Ok : false
|
||||||
|
|
||||||
|
property var selectedChatGui
|
||||||
property string remoteAddress
|
property string remoteAddress
|
||||||
onRemoteAddressChanged: console.log("ChatPage : remote address changed :", remoteAddress)
|
onRemoteAddressChanged: console.log("ChatPage : remote address changed :", remoteAddress)
|
||||||
property var remoteChatObj: UtilsCpp.getChatForAddress(remoteAddress)
|
property var remoteChatObj: UtilsCpp.getChatForAddress(remoteAddress)
|
||||||
property ChatGui remoteChat: remoteChatObj && remoteChatObj.value ? remoteChatObj.value : null
|
property var remoteChat: remoteChatObj ? remoteChatObj.value : null
|
||||||
onRemoteChatChanged: if (remoteChat) selectedChatGui = remoteChat
|
onRemoteChatChanged: {
|
||||||
|
selectedChatGui = remoteChat
|
||||||
|
}
|
||||||
|
|
||||||
onSelectedChatGuiChanged: {
|
onSelectedChatGuiChanged: {
|
||||||
if (selectedChatGui)
|
if (selectedChatGui) {
|
||||||
|
if (!listStackView.currentItem || listStackView.currentItem.objectName !== "chatListItem") {
|
||||||
|
listStackView.popToIndex(0)
|
||||||
|
if (listStackView.depth === 0 || listStackView.currentItem.objectName !== "chatListItem") listStackView.push(chatListItem)
|
||||||
|
}
|
||||||
rightPanelStackView.replace(currentChatComp,
|
rightPanelStackView.replace(currentChatComp,
|
||||||
Control.StackView.Immediate)
|
Control.StackView.Immediate)
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
rightPanelStackView.replace(emptySelection,
|
rightPanelStackView.replace(emptySelection,
|
||||||
Control.StackView.Immediate)
|
Control.StackView.Immediate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rightPanelStackView.initialItem: emptySelection
|
rightPanelStackView.initialItem: emptySelection
|
||||||
|
rightPanelStackView.visible: listStackView.currentItem && listStackView.currentItem.objectName === "chatListItem"
|
||||||
|
|
||||||
onNoItemButtonPressed: goToNewChat()
|
onNoItemButtonPressed: goToNewChat()
|
||||||
|
|
||||||
|
|
@ -206,36 +223,79 @@ AbstractMainPage {
|
||||||
//: "New chat"
|
//: "New chat"
|
||||||
text: qsTr("chat_action_start_new_chat")
|
text: qsTr("chat_action_start_new_chat")
|
||||||
color: DefaultStyle.main2_700
|
color: DefaultStyle.main2_700
|
||||||
font.pixelSize: Typography.h2.pixelSize
|
font.pixelSize: Typography.h2m.pixelSize
|
||||||
font.weight: Typography.h2.weight
|
font.weight: Typography.h2m.weight
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NewCallForm {
|
NewChatForm {
|
||||||
// id: callContactsList
|
id: newChatForm
|
||||||
// Layout.topMargin: Math.round(18 * DefaultStyle.dp)
|
Layout.fillWidth: true
|
||||||
// Layout.fillWidth: true
|
Layout.fillHeight: true
|
||||||
// Layout.fillHeight: true
|
Layout.topMargin: Math.round(18 * DefaultStyle.dp)
|
||||||
// focus: true
|
onGroupCreationRequested: {
|
||||||
// numPadPopup: numericPadPopupItem
|
console.log("groupe call requetsed")
|
||||||
// groupCallVisible: true
|
listStackView.push(groupChatItem)
|
||||||
// searchBarColor: DefaultStyle.grey_100
|
}
|
||||||
// onContactClicked: contact => {
|
onContactClicked: (contact) => {
|
||||||
// mainWindow.startCallWithContact(contact, false, callContactsList)
|
if (contact) {
|
||||||
// }
|
mainItem.remoteAddress = ""
|
||||||
// onGroupCallCreationRequested: {
|
mainItem.remoteAddress = contact.core.defaultAddress
|
||||||
// console.log("groupe call requetsed")
|
}
|
||||||
// listStackView.push(groupCallItem)
|
}
|
||||||
// }
|
}
|
||||||
// Connections {
|
}
|
||||||
// target: mainItem
|
}
|
||||||
// function onCreateCallFromSearchBarRequested() {
|
}
|
||||||
// UtilsCpp.createCall(callContactsList.searchBar.text)
|
|
||||||
// }
|
Component {
|
||||||
// }
|
id: groupChatItem
|
||||||
// }
|
GroupCreationFormLayout {
|
||||||
|
id: chatCreationLayout
|
||||||
|
|
||||||
|
objectName: "groupChatItem"
|
||||||
|
//: "Nouveau groupe"
|
||||||
|
formTitle: qsTr("chat_start_group_chat_title")
|
||||||
|
//: "Créer"
|
||||||
|
createGroupButtonText: qsTr("chat_action_start_group_chat")
|
||||||
|
|
||||||
|
property var groupChatObj
|
||||||
|
property var groupChat: groupChatObj ? groupChatObj.value : null
|
||||||
|
onGroupChatChanged: if (groupChat && groupChat.core.state === LinphoneEnums.ChatRoomState.Created) {
|
||||||
|
mainItem.selectedChatGui = groupChat
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
enabled: groupChat || false
|
||||||
|
target: groupChat?.core || null
|
||||||
|
function onChatRoomStateChanged() {
|
||||||
|
if (chatCreationLayout.groupChat.core.state === LinphoneEnums.ChatRoomState.Created) {
|
||||||
|
mainItem.selectedChatGui = chatCreationLayout.groupChat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Control.StackView.onActivated: {
|
||||||
|
addParticipantsLayout.forceActiveFocus()
|
||||||
|
}
|
||||||
|
onReturnRequested: {
|
||||||
|
listStackView.pop()
|
||||||
|
listStackView.currentItem?.forceActiveFocus()
|
||||||
|
}
|
||||||
|
onGroupCreationRequested: {
|
||||||
|
if (groupName.text.length === 0) {
|
||||||
|
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
|
||||||
|
//: "Un nom doit être donné au groupe
|
||||||
|
qsTr("group_chat_error_must_have_name"), false)
|
||||||
|
} else if (!mainItem.isRegistered) {
|
||||||
|
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
|
||||||
|
//: "Vous n'etes pas connecté"
|
||||||
|
qsTr("group_call_error_not_connected"), false)
|
||||||
|
} else {
|
||||||
|
console.log("create group chat")
|
||||||
|
chatCreationLayout.groupChatObj = UtilsCpp.createGroupChat(chatCreationLayout.groupName.text, addParticipantsLayout.selectedParticipants)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,13 @@ QtObject {
|
||||||
weight: Math.min(Math.round(800 * DefaultStyle.dp), 1000)
|
weight: Math.min(Math.round(800 * DefaultStyle.dp), 1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Title/H2M - Large bloc title
|
||||||
|
property font h2m: Qt.font( {
|
||||||
|
family: DefaultStyle.defaultFont,
|
||||||
|
pixelSize: Math.round(20 * DefaultStyle.dp),
|
||||||
|
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