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);
|
||||
mIdentifier = Utils::coreStringToAppString(chatRoom->getIdentifier());
|
||||
mChatRoomState = LinphoneEnums::fromLinphone(chatRoom->getState());
|
||||
connect(this, &ChatCore::messageListChanged, this, &ChatCore::lUpdateLastMessage);
|
||||
connect(this, &ChatCore::messagesInserted, this, &ChatCore::lUpdateLastMessage);
|
||||
connect(this, &ChatCore::messageRemoved, this, &ChatCore::lUpdateLastMessage);
|
||||
|
|
@ -132,6 +133,12 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
|
|||
});
|
||||
mChatModelConnection->makeConnectToModel(
|
||||
&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,
|
||||
[this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
|
||||
|
|
@ -277,6 +284,17 @@ LinphoneEnums::ChatMessageState ChatCore::getLastMessageState() const {
|
|||
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 {
|
||||
return mLastMessage ? new ChatMessageGui(mLastMessage) : nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public:
|
|||
Q_PROPERTY(QString lastMessageText READ getLastMessageText NOTIFY lastMessageChanged)
|
||||
Q_PROPERTY(ChatMessageGui *lastMessage READ getLastMessage 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
|
||||
unreadMessagesCountChanged)
|
||||
Q_PROPERTY(QString composingName READ getComposingName WRITE setComposingName NOTIFY composingUserChanged)
|
||||
|
|
@ -70,6 +71,9 @@ public:
|
|||
|
||||
LinphoneEnums::ChatMessageState getLastMessageState() const;
|
||||
|
||||
LinphoneEnums::ChatRoomState getChatRoomState() const;
|
||||
void setChatRoomState(LinphoneEnums::ChatRoomState state);
|
||||
|
||||
QSharedPointer<ChatMessageCore> getLastMessageCore() const;
|
||||
void setLastMessage(QSharedPointer<ChatMessageCore> lastMessage);
|
||||
|
||||
|
|
@ -96,11 +100,9 @@ public:
|
|||
|
||||
std::shared_ptr<ChatModel> getModel() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
signals:
|
||||
// used to close all the notifications when one is clicked
|
||||
void messageOpen();
|
||||
|
||||
signals:
|
||||
void lastUpdatedTimeChanged(QDateTime time);
|
||||
void lastMessageChanged();
|
||||
void titleChanged(QString title);
|
||||
|
|
@ -111,6 +113,7 @@ signals:
|
|||
void avatarUriChanged();
|
||||
void deleted();
|
||||
void composingUserChanged();
|
||||
void chatRoomStateChanged();
|
||||
|
||||
void lDeleteMessage();
|
||||
void lDelete();
|
||||
|
|
@ -134,6 +137,7 @@ private:
|
|||
QString mComposingName;
|
||||
QString mComposingAddress;
|
||||
bool mIsGroupChat = false;
|
||||
LinphoneEnums::ChatRoomState mChatRoomState;
|
||||
std::shared_ptr<ChatModel> mChatModel;
|
||||
QSharedPointer<ChatMessageCore> mLastMessage;
|
||||
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(
|
||||
&CoreModel::defaultAccountChanged,
|
||||
[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);
|
||||
}
|
||||
|
||||
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 {
|
||||
int row = index.row();
|
||||
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public:
|
|||
void connectItem(QSharedPointer<ChatCore> chat);
|
||||
|
||||
int findChatIndex(ChatGui *chat);
|
||||
void addChatInList(ChatGui *chatGui);
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
signals:
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ int ChatProxy::findChatIndex(ChatGui *chatGui) {
|
|||
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 {
|
||||
// auto l = getItemAtSource<ChatList, ChatCore>(sourceRow);
|
||||
// return l != nullptr;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public:
|
|||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
|
||||
Q_INVOKABLE int findChatIndex(ChatGui *chatGui);
|
||||
Q_INVOKABLE void addChatInList(ChatGui *chatGui);
|
||||
|
||||
signals:
|
||||
void chatRemoved(ChatGui *chat);
|
||||
|
|
|
|||
|
|
@ -467,11 +467,19 @@ QString ToolModel::computeUserAgent(const std::shared_ptr<linphone::Config> &con
|
|||
.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>
|
||||
ToolModel::getChatRoomParams(std::shared_ptr<linphone::Call> call, std::shared_ptr<linphone::Address> remoteAddress) {
|
||||
auto core = call ? call->getCore() : CoreModel::getInstance()->getCore();
|
||||
auto localAddress = call ? call->getCallLog()->getLocalAddress() : nullptr;
|
||||
if (!remoteAddress && call) remoteAddress = call->getRemoteAddress()->clone();
|
||||
remoteAddress->clean();
|
||||
auto account = findAccount(localAddress);
|
||||
if (!account) account = core->getDefaultAccount();
|
||||
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->enableGroup(false);
|
||||
//: Dummy subject
|
||||
params->setSubject(Utils::appStringToCoreString(QObject::tr("chat_dummy_subject")));
|
||||
params->setSubject("Dummy subject");
|
||||
params->setAccount(account);
|
||||
|
||||
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);
|
||||
params->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd);
|
||||
} else if (!accountParams->getInstantMessagingEncryptionMandatory()) {
|
||||
if (SettingsModel::getInstance()->getCreateEndToEndEncryptedMeetingsAndGroupCalls()) {
|
||||
if (isEndToEndEncryptedChatAvailable()) {
|
||||
qDebug() << "Account is in interop mode but LIME is available, requesting E2E encryption";
|
||||
chatParams->setBackend(linphone::ChatRoom::Backend::FlexisipChat);
|
||||
params->setSecurityLevel(linphone::Conference::SecurityLevel::EndToEnd);
|
||||
} 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);
|
||||
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 account = core->getDefaultAccount();
|
||||
if (!account) return nullptr;
|
||||
auto localAddress = account->getParams()->getIdentityAddress();
|
||||
auto localAddress = account->getParams()->getIdentityAddress()->clone();
|
||||
localAddress->clean();
|
||||
if (!localAddress || !remoteAddress) return nullptr;
|
||||
|
||||
auto params = getChatRoomParams(nullptr, remoteAddress);
|
||||
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"
|
||||
<< remoteAddress->asStringUriOnly();
|
||||
|
|
@ -581,6 +591,33 @@ std::shared_ptr<linphone::ChatRoom> ToolModel::createChatForAddress(std::shared_
|
|||
auto chatRoom = core->createChatRoom(params, participants);
|
||||
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).
|
||||
// Online = Basic Status open with no activity
|
||||
// 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
|
||||
// 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.
|
||||
|
||||
LinphoneEnums::Presence
|
||||
ToolModel::corePresenceModelToAppPresence(std::shared_ptr<const linphone::PresenceModel> presenceModel) {
|
||||
if (!presenceModel) {
|
||||
lWarning() << sLog().arg("presence model is null.");
|
||||
// lWarning() << sLog().arg("presence model is null.");
|
||||
return LinphoneEnums::Presence::Undefined;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,8 +85,11 @@ public:
|
|||
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> 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> 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
|
||||
corePresenceModelToAppPresence(std::shared_ptr<const linphone::PresenceModel> presenceModel);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ public:
|
|||
Q_PROPERTY(QString ContactUrl MEMBER ContactUrl CONSTANT)
|
||||
Q_PROPERTY(QString TranslationUrl MEMBER TranslationUrl CONSTANT)
|
||||
Q_PROPERTY(QString DefaultFont MEMBER DefaultFont CONSTANT)
|
||||
Q_PROPERTY(QString DefaultLocale MEMBER DefaultLocale CONSTANT)
|
||||
Q_PROPERTY(int maxMosaicParticipants MEMBER MaxMosaicParticipants CONSTANT)
|
||||
Q_PROPERTY(QStringList reactionsList READ getReactionsList CONSTANT)
|
||||
|
||||
|
|
|
|||
|
|
@ -1556,6 +1556,7 @@ VariantObject *Utils::getChatForAddress(QString address) {
|
|||
data->makeRequest([address, data]() {
|
||||
auto linAddr = ToolModel::interpretUrl(address);
|
||||
if (!linAddr) return QVariant();
|
||||
linAddr->clean();
|
||||
auto linphoneChatRoom = ToolModel::lookupChatForAddress(linAddr);
|
||||
if (linphoneChatRoom) {
|
||||
auto chatCore = ChatCore::create(linphoneChatRoom);
|
||||
|
|
@ -1584,6 +1585,28 @@ VariantObject *Utils::getChatForAddress(QString address) {
|
|||
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) {
|
||||
auto mainWindow = getMainWindow();
|
||||
smartShowWindow(mainWindow);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ public:
|
|||
|
||||
Q_INVOKABLE static VariantObject *getCurrentCallChat(CallGui *call);
|
||||
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 bool isEmptyMessage(QString message);
|
||||
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/Container/Carousel.qml
|
||||
view/Control/Container/CreationFormLayout.qml
|
||||
view/Control/Container/GroupCreationFormLayout.qml
|
||||
view/Control/Container/DetailLayout.qml
|
||||
view/Control/Container/FormItemLayout.qml
|
||||
view/Control/Container/ScrollBar.qml
|
||||
|
|
@ -107,6 +109,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
|||
view/Control/Tool/Prototype/PhoneNumberPrototype.qml
|
||||
|
||||
view/Page/Form/Call/NewCallForm.qml
|
||||
view/Page/Form/Chat/NewChatForm.qml
|
||||
view/Page/Form/Chat/SelectedChatView.qml
|
||||
view/Page/Form/Contact/ContactDescription.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 real busyIndicatorSize: Math.round(60 * DefaultStyle.dp)
|
||||
|
||||
property ChatGui currentChatGui
|
||||
onCurrentIndexChanged: currentChatGui = model.getAt(currentIndex) || null
|
||||
|
||||
signal resultsReceived
|
||||
|
||||
onResultsReceived: {
|
||||
|
|
@ -43,6 +46,10 @@ ListView {
|
|||
mainItem.currentIndex = -1
|
||||
mainItem.currentIndex = indexToSelect
|
||||
}
|
||||
onLayoutChanged: {
|
||||
var chatToSelect = getAt(mainItem.currentIndex)
|
||||
selectChat(mainItem.currentChatGui)
|
||||
}
|
||||
}
|
||||
// flickDeceleration: 10000
|
||||
spacing: Math.round(10 * DefaultStyle.dp)
|
||||
|
|
@ -50,6 +57,14 @@ ListView {
|
|||
function selectChat(chatGui) {
|
||||
var index = chatProxy.findChatIndex(chatGui)
|
||||
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
|
||||
|
|
@ -67,9 +82,6 @@ ListView {
|
|||
chatProxy.displayMore()
|
||||
}
|
||||
}
|
||||
onCountChanged: {
|
||||
if (count > 0 && currentIndex < 0) currentIndex = 0
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
function moveToCurrentItem() {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import QtQuick.Controls.Basic as Control
|
|||
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
import ConstantsCpp 1.0
|
||||
import ConstantsCpp
|
||||
import SettingsCpp
|
||||
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ Notification {
|
|||
property string message: notificationData ? notificationData.message : ""
|
||||
Connections {
|
||||
enabled: chat
|
||||
target: chat.core
|
||||
target: chat ? chat.core : null
|
||||
function onMessageOpen() {
|
||||
close()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,26 +7,17 @@ import Linphone
|
|||
import UtilsCpp
|
||||
import SettingsCpp
|
||||
|
||||
FocusScope {
|
||||
CreationFormLayout {
|
||||
id: mainItem
|
||||
property bool groupCallVisible
|
||||
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 contactClicked(FriendGui contact)
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: Math.round(22 * DefaultStyle.dp)
|
||||
ColumnLayout {
|
||||
spacing: Math.round(18 * DefaultStyle.dp)
|
||||
visible: mainItem.displayCurrentCalls && callList.count > 0
|
||||
//: Appel de groupe
|
||||
startGroupButtonText: qsTr("call_start_group_call_title")
|
||||
|
||||
topLayoutVisible: mainItem.displayCurrentCalls && callList.count > 0
|
||||
topContent: [
|
||||
Text {
|
||||
//: "Appels en cours"
|
||||
text: qsTr("call_transfer_active_calls_label")
|
||||
|
|
@ -34,7 +25,7 @@ FocusScope {
|
|||
pixelSize: Typography.h4.pixelSize
|
||||
weight: Typography.h4.weight
|
||||
}
|
||||
}
|
||||
},
|
||||
Flickable {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: callListBackground.height
|
||||
|
|
@ -54,84 +45,5 @@ FocusScope {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
onVisibleChanged: if (!visible) 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: grouCallButton
|
||||
}
|
||||
ColumnLayout {
|
||||
id: content
|
||||
spacing: Math.round(32 * DefaultStyle.dp)
|
||||
Button {
|
||||
id: grouCallButton
|
||||
visible: mainItem.groupCallVisible && !SettingsCpp.disableMeetingsFeature
|
||||
Layout.preferredWidth: Math.round(320 * DefaultStyle.dp)
|
||||
Layout.preferredHeight: Math.round(44 * DefaultStyle.dp)
|
||||
padding: 0
|
||||
KeyNavigation.up: searchBar
|
||||
KeyNavigation.down: contactList
|
||||
onClicked: mainItem.groupCallCreationRequested()
|
||||
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: 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 {
|
||||
anchors.fill: parent
|
||||
spacing: Math.round(15 * DefaultStyle.dp)
|
||||
ListView {
|
||||
GridView {
|
||||
id: participantList
|
||||
Layout.fillWidth: true
|
||||
visible: contentHeight > 0
|
||||
Layout.preferredHeight: contentHeight
|
||||
Layout.maximumHeight: mainItem.height / 3
|
||||
width: mainItem.width
|
||||
cellWidth: Math.round((50 + 18) * DefaultStyle.dp)
|
||||
cellHeight: Math.round(80 * DefaultStyle.dp)
|
||||
// columnCount: Math.floor(width/cellWidth)
|
||||
model: mainItem.selectedParticipants
|
||||
clip: true
|
||||
// columnSpacing: Math.round(18 * DefaultStyle.dp)
|
||||
// rowSpacing: Math.round(9 * DefaultStyle.dp)
|
||||
Keys.onPressed: (event) => {
|
||||
if(currentIndex <=0 && event.key == Qt.Key_Up){
|
||||
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 {
|
||||
height: Math.round(56 * DefaultStyle.dp)
|
||||
width: participantList.width - scrollbar.implicitWidth - Math.round(28 * DefaultStyle.dp)
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: Math.round(10 * DefaultStyle.dp)
|
||||
spacing: Math.round(4 * DefaultStyle.dp)
|
||||
width: Math.round(50 * DefaultStyle.dp)
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: Math.round(50 * DefaultStyle.dp)
|
||||
Layout.preferredHeight: Math.round(50 * DefaultStyle.dp)
|
||||
Avatar {
|
||||
Layout.preferredWidth: Math.round(45 * DefaultStyle.dp)
|
||||
Layout.preferredHeight: Math.round(45 * DefaultStyle.dp)
|
||||
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 {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: width
|
||||
width: Math.round(50 * DefaultStyle.dp)
|
||||
maximumLineCount: 1
|
||||
clip: true
|
||||
property var nameObj: UtilsCpp.getDisplayName(modelData)
|
||||
text: nameObj ? nameObj.value : ""
|
||||
font.pixelSize: Math.round(14 * DefaultStyle.dp)
|
||||
font.capitalization: Font.Capitalize
|
||||
color: DefaultStyle.main2_700
|
||||
wrapMode: Text.WrapAnywhere
|
||||
font {
|
||||
pixelSize: Typography.p3.pixelSize
|
||||
weight: Typography.p3.weight
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
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
|
||||
== LinphoneEnums.RegistrationState.Ok : false
|
||||
property int selectedParticipantsCount
|
||||
signal startGroupCallRequested
|
||||
signal createCallFromSearchBarRequested
|
||||
signal createContactRequested(string name, string address)
|
||||
signal openNumPadRequest
|
||||
|
|
@ -370,7 +369,7 @@ AbstractMainPage {
|
|||
onContactClicked: contact => {
|
||||
mainWindow.startCallWithContact(contact, false, callContactsList)
|
||||
}
|
||||
onGroupCallCreationRequested: {
|
||||
onGroupCreationRequested: {
|
||||
console.log("groupe call requetsed")
|
||||
listStackView.push(groupCallItem)
|
||||
}
|
||||
|
|
@ -387,110 +386,21 @@ AbstractMainPage {
|
|||
|
||||
Component {
|
||||
id: groupCallItem
|
||||
FocusScope {
|
||||
GroupCreationFormLayout {
|
||||
objectName: "groupCallItem"
|
||||
//: "Appel de groupe"
|
||||
formTitle: qsTr("call_start_group_call_title")
|
||||
//: "Lancer"
|
||||
createGroupButtonText: qsTr("call_action_start_group_call")
|
||||
Control.StackView.onActivated: {
|
||||
addParticipantsLayout.forceActiveFocus()
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
RowLayout {
|
||||
spacing: Math.round(10 * DefaultStyle.dp)
|
||||
visible: !SettingsCpp.disableMeetingsFeature
|
||||
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: listStackView
|
||||
KeyNavigation.right: groupCallButton
|
||||
KeyNavigation.left: groupCallButton
|
||||
onClicked: {
|
||||
onReturnRequested: {
|
||||
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) {
|
||||
onGroupCreationRequested: {
|
||||
if (groupName.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)
|
||||
|
|
@ -499,17 +409,7 @@ AbstractMainPage {
|
|||
//: "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)
|
||||
}
|
||||
}
|
||||
}
|
||||
UtilsCpp.createGroupCall(groupName.text, addParticipantsLayout.selectedParticipants)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,24 +16,41 @@ AbstractMainPage {
|
|||
emptyListText: qsTr("chat_empty_title")
|
||||
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
|
||||
onRemoteAddressChanged: console.log("ChatPage : remote address changed :", remoteAddress)
|
||||
property var remoteChatObj: UtilsCpp.getChatForAddress(remoteAddress)
|
||||
property ChatGui remoteChat: remoteChatObj && remoteChatObj.value ? remoteChatObj.value : null
|
||||
onRemoteChatChanged: if (remoteChat) selectedChatGui = remoteChat
|
||||
property var remoteChat: remoteChatObj ? remoteChatObj.value : null
|
||||
onRemoteChatChanged: {
|
||||
selectedChatGui = remoteChat
|
||||
}
|
||||
|
||||
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,
|
||||
Control.StackView.Immediate)
|
||||
else
|
||||
}
|
||||
else {
|
||||
rightPanelStackView.replace(emptySelection,
|
||||
Control.StackView.Immediate)
|
||||
}
|
||||
}
|
||||
|
||||
rightPanelStackView.initialItem: emptySelection
|
||||
rightPanelStackView.visible: listStackView.currentItem && listStackView.currentItem.objectName === "chatListItem"
|
||||
|
||||
onNoItemButtonPressed: goToNewChat()
|
||||
|
||||
|
|
@ -206,36 +223,79 @@ AbstractMainPage {
|
|||
//: "New chat"
|
||||
text: qsTr("chat_action_start_new_chat")
|
||||
color: DefaultStyle.main2_700
|
||||
font.pixelSize: Typography.h2.pixelSize
|
||||
font.weight: Typography.h2.weight
|
||||
font.pixelSize: Typography.h2m.pixelSize
|
||||
font.weight: Typography.h2m.weight
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
// NewCallForm {
|
||||
// id: callContactsList
|
||||
// Layout.topMargin: Math.round(18 * DefaultStyle.dp)
|
||||
// Layout.fillWidth: true
|
||||
// Layout.fillHeight: true
|
||||
// focus: true
|
||||
// numPadPopup: numericPadPopupItem
|
||||
// groupCallVisible: true
|
||||
// searchBarColor: DefaultStyle.grey_100
|
||||
// onContactClicked: contact => {
|
||||
// mainWindow.startCallWithContact(contact, false, callContactsList)
|
||||
// }
|
||||
// onGroupCallCreationRequested: {
|
||||
// console.log("groupe call requetsed")
|
||||
// listStackView.push(groupCallItem)
|
||||
// }
|
||||
// Connections {
|
||||
// target: mainItem
|
||||
// function onCreateCallFromSearchBarRequested() {
|
||||
// UtilsCpp.createCall(callContactsList.searchBar.text)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
NewChatForm {
|
||||
id: newChatForm
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: Math.round(18 * DefaultStyle.dp)
|
||||
onGroupCreationRequested: {
|
||||
console.log("groupe call requetsed")
|
||||
listStackView.push(groupChatItem)
|
||||
}
|
||||
onContactClicked: (contact) => {
|
||||
if (contact) {
|
||||
mainItem.remoteAddress = ""
|
||||
mainItem.remoteAddress = contact.core.defaultAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
// 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
|
||||
property font h2: Qt.font( {
|
||||
family: DefaultStyle.defaultFont,
|
||||
|
|
|
|||
Loading…
Reference in a new issue