zrtp validation toast + blason
security level for specific address dtmfs ui fixes key navigation contact page
This commit is contained in:
parent
16e1b7b7c2
commit
1e234cdc25
31 changed files with 374 additions and 242 deletions
|
|
@ -385,6 +385,9 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
|
||||||
mCallModelConnection->invokeToModel(
|
mCallModelConnection->invokeToModel(
|
||||||
[this, model = gui->getCore()->getModel()]() { mCallModel->setVideoSourceDescriptorModel(model); });
|
[this, model = gui->getCore()->getModel()]() { mCallModel->setVideoSourceDescriptorModel(model); });
|
||||||
});
|
});
|
||||||
|
mCallModelConnection->makeConnectToCore(&CallCore::lSendDtmf, [this](QString dtmf) {
|
||||||
|
mCallModelConnection->invokeToModel([this, dtmf]() { mCallModel->sendDtmf(dtmf); });
|
||||||
|
});
|
||||||
|
|
||||||
mCallModelConnection->makeConnectToModel(&CallModel::videoDescriptorChanged, [this]() {
|
mCallModelConnection->makeConnectToModel(&CallModel::videoDescriptorChanged, [this]() {
|
||||||
auto videoSource = mCallModel->getMonitor()->getVideoSource();
|
auto videoSource = mCallModel->getMonitor()->getVideoSource();
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,7 @@ signals:
|
||||||
void lSetOutputAudioDevice(QString id);
|
void lSetOutputAudioDevice(QString id);
|
||||||
void lSetConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout);
|
void lSetConferenceVideoLayout(LinphoneEnums::ConferenceLayout layout);
|
||||||
void lSetVideoSourceDescriptor(VideoSourceDescriptorGui *gui);
|
void lSetVideoSourceDescriptor(VideoSourceDescriptorGui *gui);
|
||||||
|
void lSendDtmf(QString dtmf);
|
||||||
|
|
||||||
/* TODO
|
/* TODO
|
||||||
Q_INVOKABLE void acceptWithVideo();
|
Q_INVOKABLE void acceptWithVideo();
|
||||||
|
|
@ -302,7 +303,6 @@ signals:
|
||||||
|
|
||||||
Q_INVOKABLE void takeSnapshot();
|
Q_INVOKABLE void takeSnapshot();
|
||||||
|
|
||||||
Q_INVOKABLE void sendDtmf(const QString &dtmf);
|
|
||||||
Q_INVOKABLE void verifyAuthenticationToken(bool verify);
|
Q_INVOKABLE void verifyAuthenticationToken(bool verify);
|
||||||
Q_INVOKABLE void updateStreams();
|
Q_INVOKABLE void updateStreams();
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -412,6 +412,16 @@ void FriendCore::setDevices(QVariantList devices) {
|
||||||
emit devicesChanged();
|
emit devicesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinphoneEnums::SecurityLevel FriendCore::getSecurityLevelForAddress(const QString &address) const {
|
||||||
|
for (auto &device : mDeviceList) {
|
||||||
|
auto map = device.toMap();
|
||||||
|
if (map["address"].toString() == address) {
|
||||||
|
return map["securityLevel"].value<LinphoneEnums::SecurityLevel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LinphoneEnums::SecurityLevel::None;
|
||||||
|
}
|
||||||
|
|
||||||
QString FriendCore::getDefaultAddress() const {
|
QString FriendCore::getDefaultAddress() const {
|
||||||
return mDefaultAddress;
|
return mDefaultAddress;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ public:
|
||||||
QList<QVariant> getDevices() const;
|
QList<QVariant> getDevices() const;
|
||||||
void updateVerifiedDevicesCount();
|
void updateVerifiedDevicesCount();
|
||||||
void setDevices(QVariantList devices);
|
void setDevices(QVariantList devices);
|
||||||
|
Q_INVOKABLE LinphoneEnums::SecurityLevel getSecurityLevelForAddress(const QString &address) const;
|
||||||
|
|
||||||
LinphoneEnums::ConsolidatedPresence getConsolidatedPresence() const;
|
LinphoneEnums::ConsolidatedPresence getConsolidatedPresence() const;
|
||||||
void setConsolidatedPresence(LinphoneEnums::ConsolidatedPresence presence);
|
void setConsolidatedPresence(LinphoneEnums::ConsolidatedPresence presence);
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
|
@ -382,6 +382,13 @@ void CallModel::setVideoSourceDescriptorModel(std::shared_ptr<VideoSourceDescrip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CallModel::sendDtmf(const QString &dtmf) {
|
||||||
|
const char key = dtmf.constData()[0].toLatin1();
|
||||||
|
qInfo() << QStringLiteral("Send dtmf: `%1`.").arg(key);
|
||||||
|
if (mMonitor) mMonitor->sendDtmf(key);
|
||||||
|
CoreModel::getInstance()->getCore()->playDtmf(key, dtmfSoundDelay);
|
||||||
|
}
|
||||||
|
|
||||||
void CallModel::onDtmfReceived(const std::shared_ptr<linphone::Call> &call, int dtmf) {
|
void CallModel::onDtmfReceived(const std::shared_ptr<linphone::Call> &call, int dtmf) {
|
||||||
emit dtmfReceived(call, dtmf);
|
emit dtmfReceived(call, dtmf);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,8 @@ public:
|
||||||
const std::shared_ptr<const linphone::CallParams> ¤tParams,
|
const std::shared_ptr<const linphone::CallParams> ¤tParams,
|
||||||
bool enable);
|
bool enable);
|
||||||
|
|
||||||
|
void sendDtmf(const QString &dtmf);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void microphoneMutedChanged(bool isMuted);
|
void microphoneMutedChanged(bool isMuted);
|
||||||
void speakerMutedChanged(bool isMuted);
|
void speakerMutedChanged(bool isMuted);
|
||||||
|
|
@ -111,6 +113,7 @@ private:
|
||||||
QTimer mMicroVolumeTimer;
|
QTimer mMicroVolumeTimer;
|
||||||
std::shared_ptr<linphone::Conference> mConference;
|
std::shared_ptr<linphone::Conference> mConference;
|
||||||
LinphoneEnums::ConferenceLayout mConferenceVideoLayout;
|
LinphoneEnums::ConferenceLayout mConferenceVideoLayout;
|
||||||
|
static constexpr int dtmfSoundDelay = 200;
|
||||||
|
|
||||||
DECLARE_ABSTRACT_OBJECT
|
DECLARE_ABSTRACT_OBJECT
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,11 @@ QString FriendModel::getPictureUri() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FriendModel::getVCardAsString() const {
|
QString FriendModel::getVCardAsString() const {
|
||||||
|
auto vcard = mMonitor->getVcard();
|
||||||
|
bool created = false;
|
||||||
|
if (!vcard) {
|
||||||
|
created = mMonitor->createVcard(mMonitor->getName());
|
||||||
|
}
|
||||||
assert(mMonitor->getVcard());
|
assert(mMonitor->getVcard());
|
||||||
return Utils::coreStringToAppString(mMonitor->getVcard()->asVcard4String());
|
return Utils::coreStringToAppString(mMonitor->getVcard()->asVcard4String());
|
||||||
}
|
}
|
||||||
|
|
@ -279,6 +284,15 @@ std::list<std::shared_ptr<linphone::FriendDevice>> FriendModel::getDevices() con
|
||||||
return mMonitor->getDevices();
|
return mMonitor->getDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linphone::SecurityLevel FriendModel::getSecurityLevel() const {
|
||||||
|
return mMonitor->getSecurityLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
linphone::SecurityLevel
|
||||||
|
FriendModel::getSecurityLevelForAddress(const std::shared_ptr<linphone::Address> address) const {
|
||||||
|
return mMonitor->getSecurityLevelForAddress(address);
|
||||||
|
}
|
||||||
|
|
||||||
void FriendModel::setPictureUri(const QString &uri) {
|
void FriendModel::setPictureUri(const QString &uri) {
|
||||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
auto oldPictureUri = Utils::coreStringToAppString(mMonitor->getPhoto());
|
auto oldPictureUri = Utils::coreStringToAppString(mMonitor->getPhoto());
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ public:
|
||||||
QString getPictureUri() const;
|
QString getPictureUri() const;
|
||||||
QString getVCardAsString() const;
|
QString getVCardAsString() const;
|
||||||
std::list<std::shared_ptr<linphone::FriendDevice>> getDevices() const;
|
std::list<std::shared_ptr<linphone::FriendDevice>> getDevices() const;
|
||||||
|
linphone::SecurityLevel getSecurityLevel() const;
|
||||||
|
linphone::SecurityLevel getSecurityLevelForAddress(const std::shared_ptr<linphone::Address> address) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setAddress(const std::shared_ptr<linphone::Address> &address);
|
void setAddress(const std::shared_ptr<linphone::Address> &address);
|
||||||
|
|
|
||||||
|
|
@ -367,6 +367,24 @@ VariantObject *Utils::findFriendByAddress(const QString &address) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VariantObject *Utils::getFriendAddressSecurityLevel(const QString &address) {
|
||||||
|
VariantObject *data = new VariantObject();
|
||||||
|
if (!data) return nullptr;
|
||||||
|
data->makeRequest([address]() {
|
||||||
|
auto defaultFriendList = CoreModel::getInstance()->getCore()->getDefaultFriendList();
|
||||||
|
if (!defaultFriendList) return QVariant();
|
||||||
|
auto linphoneAddr = ToolModel::interpretUrl(address);
|
||||||
|
auto linFriend = CoreModel::getInstance()->getCore()->findFriend(linphoneAddr);
|
||||||
|
if (!linFriend) return QVariant();
|
||||||
|
auto linAddr = ToolModel::interpretUrl(address);
|
||||||
|
if (!linAddr) return QVariant();
|
||||||
|
auto secuLevel = linFriend->getSecurityLevelForAddress(linAddr);
|
||||||
|
return QVariant::fromValue(LinphoneEnums::fromLinphone(secuLevel));
|
||||||
|
});
|
||||||
|
data->requestValue();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
QString Utils::generateSavedFilename(const QString &from, const QString &to) {
|
QString Utils::generateSavedFilename(const QString &from, const QString &to) {
|
||||||
auto escape = [](const QString &str) {
|
auto escape = [](const QString &str) {
|
||||||
constexpr char ReservedCharacters[] = "[<|>|:|\"|/|\\\\|\\?|\\*|\\+|\\||_|-]+";
|
constexpr char ReservedCharacters[] = "[<|>|:|\"|/|\\\\|\\?|\\*|\\+|\\||_|-]+";
|
||||||
|
|
@ -1328,3 +1346,8 @@ bool Utils::isUsername(const QString &txt) {
|
||||||
void Utils::useFetchConfig(const QString &configUrl) {
|
void Utils::useFetchConfig(const QString &configUrl) {
|
||||||
App::getInstance()->receivedMessage(0, ("fetch-config=" + configUrl).toLocal8Bit());
|
App::getInstance()->receivedMessage(0, ("fetch-config=" + configUrl).toLocal8Bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utils::playDtmf(const QString &dtmf) {
|
||||||
|
const char key = dtmf.constData()[0].toLatin1();
|
||||||
|
App::postModelSync([key]() { CoreModel::getInstance()->getCore()->playDtmf(key, 200); });
|
||||||
|
}
|
||||||
|
|
@ -120,12 +120,14 @@ public:
|
||||||
Q_INVOKABLE static bool isValidURL(const QString &url);
|
Q_INVOKABLE static bool isValidURL(const QString &url);
|
||||||
Q_INVOKABLE static QString findAvatarByAddress(const QString &address);
|
Q_INVOKABLE static QString findAvatarByAddress(const QString &address);
|
||||||
Q_INVOKABLE static VariantObject *findFriendByAddress(const QString &address);
|
Q_INVOKABLE static VariantObject *findFriendByAddress(const QString &address);
|
||||||
|
Q_INVOKABLE static VariantObject *getFriendAddressSecurityLevel(const QString &address);
|
||||||
static QString generateSavedFilename(const QString &from, const QString &to);
|
static QString generateSavedFilename(const QString &from, const QString &to);
|
||||||
Q_INVOKABLE static bool isMe(const QString &address);
|
Q_INVOKABLE static bool isMe(const QString &address);
|
||||||
Q_INVOKABLE static bool isLocal(const QString &address);
|
Q_INVOKABLE static bool isLocal(const QString &address);
|
||||||
Q_INVOKABLE static bool isUsername(const QString &txt); // Regex check
|
Q_INVOKABLE static bool isUsername(const QString &txt); // Regex check
|
||||||
static QString getCountryName(const QLocale::Territory &p_country);
|
static QString getCountryName(const QLocale::Territory &p_country);
|
||||||
Q_INVOKABLE static void useFetchConfig(const QString &configUrl);
|
Q_INVOKABLE static void useFetchConfig(const QString &configUrl);
|
||||||
|
Q_INVOKABLE void playDtmf(const QString &dtmf);
|
||||||
|
|
||||||
static QString getApplicationProduct();
|
static QString getApplicationProduct();
|
||||||
static QString getOsProduct();
|
static QString getOsProduct();
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ AppWindow {
|
||||||
|
|
||||||
onCallStateChanged: {
|
onCallStateChanged: {
|
||||||
if (callState === LinphoneEnums.CallState.Connected || callState === LinphoneEnums.CallState.StreamsRunning) {
|
if (callState === LinphoneEnums.CallState.Connected || callState === LinphoneEnums.CallState.StreamsRunning) {
|
||||||
if (middleItemStackView.currentItem.objectName != inCallItem) {
|
if (middleItemStackView.currentItem.objectName != "inCallItem") {
|
||||||
middleItemStackView.replace(inCallItem)
|
middleItemStackView.replace(inCallItem)
|
||||||
bottomButtonsLayout.visible = true
|
bottomButtonsLayout.visible = true
|
||||||
}
|
}
|
||||||
|
|
@ -34,9 +34,11 @@ AppWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (callState === LinphoneEnums.CallState.Error || callState === LinphoneEnums.CallState.End) {
|
else if (callState === LinphoneEnums.CallState.Error || callState === LinphoneEnums.CallState.End) {
|
||||||
|
zrtpValidation.close()
|
||||||
callEnded(call)
|
callEnded(call)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTransferStateChanged: {
|
onTransferStateChanged: {
|
||||||
console.log("Transfer state:", transferState)
|
console.log("Transfer state:", transferState)
|
||||||
if (transferState === LinphoneEnums.CallState.Error) {
|
if (transferState === LinphoneEnums.CallState.Error) {
|
||||||
|
|
@ -115,12 +117,21 @@ AppWindow {
|
||||||
target: call && call.core
|
target: call && call.core
|
||||||
function onRemoteVideoEnabledChanged() { console.log("remote video enabled", call.core.remoteVideoEnabled)}
|
function onRemoteVideoEnabledChanged() { console.log("remote video enabled", call.core.remoteVideoEnabled)}
|
||||||
function onSecurityUpdated() {
|
function onSecurityUpdated() {
|
||||||
if (call.core.encryption != LinphoneEnums.MediaEncryption.Zrtp || call.core.tokenVerified) {
|
if (call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp) {
|
||||||
|
if (call.core.tokenVerified) {
|
||||||
zrtpValidation.close()
|
zrtpValidation.close()
|
||||||
}
|
zrtpValidationToast.open()
|
||||||
else if(call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp) {
|
} else {
|
||||||
zrtpValidation.open()
|
zrtpValidation.open()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
zrtpValidation.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function onTokenVerified() {
|
||||||
|
if (!zrtpValidation.isTokenVerified) {
|
||||||
|
zrtpValidation.securityError = true
|
||||||
|
} else zrtpValidation.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,6 +233,55 @@ AppWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Timer {
|
||||||
|
id: autoCloseZrtpToast
|
||||||
|
interval: 4000
|
||||||
|
onTriggered: {
|
||||||
|
zrtpValidationToast.y = -zrtpValidationToast.height*2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Control.Control {
|
||||||
|
id: zrtpValidationToast
|
||||||
|
// width: 269 * DefaultStyle.dp
|
||||||
|
y: -height*2
|
||||||
|
z: 1
|
||||||
|
topPadding: 8 * DefaultStyle.dp
|
||||||
|
bottomPadding: 8 * DefaultStyle.dp
|
||||||
|
leftPadding: 50 * DefaultStyle.dp
|
||||||
|
rightPadding: 50 * DefaultStyle.dp
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
clip: true
|
||||||
|
function open() {
|
||||||
|
y = headerItem.height/2
|
||||||
|
autoCloseZrtpToast.restart()
|
||||||
|
}
|
||||||
|
Behavior on y {NumberAnimation {duration: 1000}}
|
||||||
|
background: Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: DefaultStyle.grey_0
|
||||||
|
border.color: DefaultStyle.info_500_main
|
||||||
|
border.width: 1 * DefaultStyle.dp
|
||||||
|
radius: 50 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
contentItem: RowLayout {
|
||||||
|
// anchors.centerIn: parent
|
||||||
|
Image {
|
||||||
|
source: AppIcons.trusted
|
||||||
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||||
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
color: DefaultStyle.info_500_main
|
||||||
|
text: qsTr("Appareil vérifié")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font {
|
||||||
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/************************* CONTENT ********************************/
|
/************************* CONTENT ********************************/
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -233,6 +293,7 @@ AppWindow {
|
||||||
anchors.bottomMargin: 10 * DefaultStyle.dp
|
anchors.bottomMargin: 10 * DefaultStyle.dp
|
||||||
anchors.topMargin: 10 * DefaultStyle.dp
|
anchors.topMargin: 10 * DefaultStyle.dp
|
||||||
Item {
|
Item {
|
||||||
|
id: headerItem
|
||||||
Layout.margins: 10 * DefaultStyle.dp
|
Layout.margins: 10 * DefaultStyle.dp
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.minimumHeight: 25 * DefaultStyle.dp
|
Layout.minimumHeight: 25 * DefaultStyle.dp
|
||||||
|
|
@ -710,7 +771,7 @@ AppWindow {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
Avatar {
|
Avatar {
|
||||||
id: delegateAvatar
|
id: delegateAvatar
|
||||||
address: modelData.core.peerAddress
|
_address: modelData.core.peerAddress
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
|
|
@ -1176,6 +1237,7 @@ AppWindow {
|
||||||
id: waitingRoom
|
id: waitingRoom
|
||||||
WaitingRoom {
|
WaitingRoom {
|
||||||
id: waitingRoomIn
|
id: waitingRoomIn
|
||||||
|
objectName: "waitingRoom"
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
onSettingsButtonCheckedChanged: {
|
onSettingsButtonCheckedChanged: {
|
||||||
if (settingsButtonChecked) {
|
if (settingsButtonChecked) {
|
||||||
|
|
@ -1187,21 +1249,21 @@ AppWindow {
|
||||||
}
|
}
|
||||||
Binding {
|
Binding {
|
||||||
target: callStatusIcon
|
target: callStatusIcon
|
||||||
when: middleItemStackView.currentItem === waitingRoomIn
|
when: middleItemStackView.currentItem.objectName === "waitingRoom"
|
||||||
property: "imageSource"
|
property: "imageSource"
|
||||||
value: AppIcons.usersThree
|
value: AppIcons.usersThree
|
||||||
restoreMode: Binding.RestoreBindingOrValue
|
restoreMode: Binding.RestoreBindingOrValue
|
||||||
}
|
}
|
||||||
Binding {
|
Binding {
|
||||||
target: callStatusText
|
target: callStatusText
|
||||||
when: middleItemStackView.currentItem === waitingRoomIn
|
when: middleItemStackView.currentItem.objectName === "waitingRoom"
|
||||||
property: "text"
|
property: "text"
|
||||||
value: waitingRoomIn.conferenceInfo ? waitingRoomIn.conferenceInfo.core.subject : ''
|
value: waitingRoomIn.conferenceInfo ? waitingRoomIn.conferenceInfo.core.subject : ''
|
||||||
restoreMode: Binding.RestoreBindingOrValue
|
restoreMode: Binding.RestoreBindingOrValue
|
||||||
}
|
}
|
||||||
Binding {
|
Binding {
|
||||||
target: conferenceDate
|
target: conferenceDate
|
||||||
when: middleItemStackView.currentItem === waitingRoomIn
|
when: middleItemStackView.currentItem.objectName === "waitingRoom"
|
||||||
property: "text"
|
property: "text"
|
||||||
value: waitingRoomIn.conferenceInfo ? waitingRoomIn.conferenceInfo.core.startEndDateString : ''
|
value: waitingRoomIn.conferenceInfo ? waitingRoomIn.conferenceInfo.core.startEndDateString : ''
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ Item {
|
||||||
|
|
||||||
AccountProxy {
|
AccountProxy {
|
||||||
id: accountProxy
|
id: accountProxy
|
||||||
onDefaultAccountChanged: if (tabbar.currentIndex === 0) defaultAccount.core.lResetMissedCalls()
|
onDefaultAccountChanged: if (tabbar.currentIndex === 0 && defaultAccount) defaultAccount.core.lResetMissedCalls()
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
|
@ -107,7 +107,6 @@ Item {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.preferredWidth: 82 * DefaultStyle.dp
|
Layout.preferredWidth: 82 * DefaultStyle.dp
|
||||||
defaultAccount: accountProxy.defaultAccount
|
defaultAccount: accountProxy.defaultAccount
|
||||||
property int unreadMessages: defaultAccount.core.unreadMessageNotifications
|
|
||||||
currentIndex: SettingsCpp.getLastActiveTabIndex()
|
currentIndex: SettingsCpp.getLastActiveTabIndex()
|
||||||
model: [
|
model: [
|
||||||
{icon: AppIcons.phone, selectedIcon: AppIcons.phoneSelected, label: qsTr("Appels")},
|
{icon: AppIcons.phone, selectedIcon: AppIcons.phoneSelected, label: qsTr("Appels")},
|
||||||
|
|
@ -117,7 +116,7 @@ Item {
|
||||||
]
|
]
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
SettingsCpp.setLastActiveTabIndex(currentIndex)
|
SettingsCpp.setLastActiveTabIndex(currentIndex)
|
||||||
if (currentIndex === 0) accountProxy.defaultAccount.core.lResetMissedCalls()
|
if (currentIndex === 0 && accountProxy.defaultAccount) accountProxy.defaultAccount.core.lResetMissedCalls()
|
||||||
if (mainItem.contextualMenuOpenedComponent) {
|
if (mainItem.contextualMenuOpenedComponent) {
|
||||||
closeContextualMenuComponent()
|
closeContextualMenuComponent()
|
||||||
}
|
}
|
||||||
|
|
@ -304,7 +303,7 @@ Item {
|
||||||
Avatar {
|
Avatar {
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
address: magicSearchBar.text
|
_address: magicSearchBar.text
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Text {
|
Text {
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ FocusScope {
|
||||||
id: searchBar
|
id: searchBar
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.rightMargin: 39 * DefaultStyle.dp
|
||||||
Layout.maximumWidth: mainItem.width
|
Layout.maximumWidth: mainItem.width
|
||||||
focus: true
|
focus: true
|
||||||
color: mainItem.searchBarColor
|
color: mainItem.searchBarColor
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,26 @@ StackView {
|
||||||
: contact
|
: contact
|
||||||
? contact.core.defaultAddress
|
? contact.core.defaultAddress
|
||||||
: ''
|
: ''
|
||||||
property string address: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(_address) : _address
|
readonly property string address: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(_address) : _address
|
||||||
property var displayNameObj: UtilsCpp.getDisplayName(address)
|
property var displayNameObj: UtilsCpp.getDisplayName(_address)
|
||||||
property string displayNameVal: displayNameObj ? displayNameObj.value : ""
|
property string displayNameVal: displayNameObj ? displayNameObj.value : ""
|
||||||
property bool haveAvatar: (account && account.core.pictureUri )
|
property bool haveAvatar: (account && account.core.pictureUri )
|
||||||
|| (contact && contact.core.pictureUri)
|
|| (contact && contact.core.pictureUri)
|
||||||
|| computedAvatarUri.length != 0
|
|| computedAvatarUri.length != 0
|
||||||
property string computedAvatarUri: UtilsCpp.findAvatarByAddress(address)
|
property string computedAvatarUri: UtilsCpp.findAvatarByAddress(_address)
|
||||||
|
|
||||||
onHaveAvatarChanged: replace(haveAvatar ? avatar : initials, StackView.Immediate)
|
onHaveAvatarChanged: replace(haveAvatar ? avatar : initials, StackView.Immediate)
|
||||||
|
|
||||||
property bool secured: contact
|
property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address)
|
||||||
|
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
|
||||||
|
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
||||||
|
? call.core.tokenVerified
|
||||||
|
: contact
|
||||||
? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount === contact.core.devices.length
|
? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount === contact.core.devices.length
|
||||||
: false
|
: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncrypted
|
||||||
|
|
||||||
|
property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe
|
||||||
|
|
||||||
property bool displayPresence: (account || contact) && (account
|
property bool displayPresence: (account || contact) && (account
|
||||||
? account.core.registrationState != LinphoneEnums.RegistrationState.Progress && account.core.registrationState != LinphoneEnums.RegistrationState.Refreshing
|
? account.core.registrationState != LinphoneEnums.RegistrationState.Progress && account.core.registrationState != LinphoneEnums.RegistrationState.Refreshing
|
||||||
: contact.core.consolidatedPresence != LinphoneEnums.ConsolidatedPresence.Offline)
|
: contact.core.consolidatedPresence != LinphoneEnums.ConsolidatedPresence.Offline)
|
||||||
|
|
@ -43,17 +50,17 @@ StackView {
|
||||||
initialItem: haveAvatar ? avatar : initials
|
initialItem: haveAvatar ? avatar : initials
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: mainItem.secured
|
visible: mainItem.secured || mainItem.securityBreach
|
||||||
anchors.fill: mainItem.currentItem
|
anchors.fill: mainItem.currentItem
|
||||||
radius: mainItem.width / 2
|
radius: mainItem.width / 2
|
||||||
z: 1
|
z: 1
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border {
|
border {
|
||||||
width: 3 * DefaultStyle.dp
|
width: 3 * DefaultStyle.dp
|
||||||
color: DefaultStyle.info_500_main
|
color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500main
|
||||||
}
|
}
|
||||||
Image {
|
Image {
|
||||||
source: AppIcons.trusted
|
source: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted
|
||||||
x: mainItem.width / 7
|
x: mainItem.width / 7
|
||||||
width: mainItem.width / 4.5
|
width: mainItem.width / 4.5
|
||||||
height: width
|
height: width
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@ RightPanelLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
if (text.length != 0) mainItem.contact.core.appendAddress(text)
|
if (text != "sip:") mainItem.contact.core.appendAddress(text)
|
||||||
text = "sip:"
|
text = "sip:"
|
||||||
}
|
}
|
||||||
Component.onCompleted: text = "sip:"
|
Component.onCompleted: text = "sip:"
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ Item {
|
||||||
visible: !joiningView.visible
|
visible: !joiningView.visible
|
||||||
account: mainItem.account
|
account: mainItem.account
|
||||||
call: !mainItem.previewEnabled ? mainItem.call : null
|
call: !mainItem.previewEnabled ? mainItem.call : null
|
||||||
address: mainItem.peerAddress
|
_address: mainItem.peerAddress
|
||||||
}
|
}
|
||||||
ColumnLayout{
|
ColumnLayout{
|
||||||
id: joiningView
|
id: joiningView
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ Popup {
|
||||||
signal accepted()
|
signal accepted()
|
||||||
signal rejected()
|
signal rejected()
|
||||||
|
|
||||||
contentItem: FocusScope{
|
contentItem: FocusScope {
|
||||||
height: child.implicitHeight
|
|
||||||
width: child.implicitWidth
|
width: child.implicitWidth
|
||||||
|
height: child.implicitHeight
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if(visible) forceActiveFocus()
|
if(visible) forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +44,7 @@ Popup {
|
||||||
id: child
|
id: child
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: 15 * DefaultStyle.dp
|
spacing: 15 * DefaultStyle.dp
|
||||||
|
|
||||||
Text{
|
Text{
|
||||||
id: titleText
|
id: titleText
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -94,9 +95,8 @@ Popup {
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: contentLayout
|
id: contentLayout
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.fillHeight: false
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@ FocusScope {
|
||||||
Avatar {
|
Avatar {
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
address: modelData.address
|
_address: modelData.address
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: modelData.displayName
|
text: modelData.displayName
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,10 @@ import QtQuick.Controls as Control
|
||||||
import QtQuick.Layouts as Layout
|
import QtQuick.Layouts as Layout
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import Linphone
|
import Linphone
|
||||||
|
import UtilsCpp
|
||||||
|
|
||||||
Control.Popup {
|
Control.Popup {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
signal buttonPressed(string text)
|
|
||||||
signal launchCall()
|
|
||||||
signal wipe()
|
|
||||||
property bool closeButtonVisible: true
|
property bool closeButtonVisible: true
|
||||||
property bool roundedBottom: false
|
property bool roundedBottom: false
|
||||||
closePolicy: Control.Popup.CloseOnEscape
|
closePolicy: Control.Popup.CloseOnEscape
|
||||||
|
|
@ -17,6 +15,16 @@ Control.Popup {
|
||||||
topPadding: 41 * DefaultStyle.dp
|
topPadding: 41 * DefaultStyle.dp
|
||||||
bottomPadding: 18 * DefaultStyle.dp
|
bottomPadding: 18 * DefaultStyle.dp
|
||||||
onOpened: numPad.forceActiveFocus()
|
onOpened: numPad.forceActiveFocus()
|
||||||
|
signal buttonPressed(string text)
|
||||||
|
onButtonPressed: (text) => {
|
||||||
|
if (callsModel.currentCall) callsModel.currentCall.core.lSendDtmf(text)
|
||||||
|
else UtilsCpp.playDtmf(text)
|
||||||
|
}
|
||||||
|
signal launchCall()
|
||||||
|
signal wipe()
|
||||||
|
CallProxy{
|
||||||
|
id: callsModel
|
||||||
|
}
|
||||||
background: Item {
|
background: Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ ListView {
|
||||||
Avatar {
|
Avatar {
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
address: modelData.core.address
|
_address: modelData.core.address
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: modelData.core.displayName
|
text: modelData.core.displayName
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ ListView {
|
||||||
Avatar {
|
Avatar {
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
address: modelData.core.sipAddress
|
_address: modelData.core.sipAddress
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: modelData.core.displayName
|
text: modelData.core.displayName
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ Control.TabBar {
|
||||||
|
|
||||||
property AccountGui defaultAccount
|
property AccountGui defaultAccount
|
||||||
onDefaultAccountChanged: {
|
onDefaultAccountChanged: {
|
||||||
defaultAccount.core.lRefreshNotifications()
|
if (defaultAccount) defaultAccount.core.lRefreshNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
component UnreadNotification: Rectangle {
|
component UnreadNotification: Rectangle {
|
||||||
|
|
@ -91,7 +91,13 @@ Control.TabBar {
|
||||||
|
|
||||||
visible: modelData?.visible != undefined ? modelData?.visible : true
|
visible: modelData?.visible != undefined ? modelData?.visible : true
|
||||||
UnreadNotification {
|
UnreadNotification {
|
||||||
unread: index == 0 ? defaultAccount.core.unreadCallNotifications : index == 2 ? defaultAccount.core.unreadMessageNotifications : 0// modelData.unreadNotifications
|
unread: !defaultAccount
|
||||||
|
? -1
|
||||||
|
: index == 0
|
||||||
|
? defaultAccount.core.unreadCallNotifications
|
||||||
|
: index == 2
|
||||||
|
? defaultAccount.core.unreadMessageNotifications
|
||||||
|
: 0
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 15 * DefaultStyle.dp
|
anchors.rightMargin: 15 * DefaultStyle.dp
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ Dialog {
|
||||||
width: 436 * DefaultStyle.dp
|
width: 436 * DefaultStyle.dp
|
||||||
rightPadding: 0 * DefaultStyle.dp
|
rightPadding: 0 * DefaultStyle.dp
|
||||||
leftPadding: 0 * DefaultStyle.dp
|
leftPadding: 0 * DefaultStyle.dp
|
||||||
topPadding: 85 * DefaultStyle.dp + 23 * DefaultStyle.dp
|
topPadding: 85 * DefaultStyle.dp + 24 * DefaultStyle.dp
|
||||||
bottomPadding: 24 * DefaultStyle.dp
|
bottomPadding: 24 * DefaultStyle.dp
|
||||||
modal: true
|
modal: true
|
||||||
closePolicy: Popup.NoAutoClose
|
closePolicy: Popup.NoAutoClose
|
||||||
|
|
@ -21,25 +21,7 @@ Dialog {
|
||||||
property bool isTokenVerified: call && call.core.tokenVerified || false
|
property bool isTokenVerified: call && call.core.tokenVerified || false
|
||||||
property bool isCaseMismatch: call && call.core.isMismatch || false
|
property bool isCaseMismatch: call && call.core.isMismatch || false
|
||||||
property bool securityError: false
|
property bool securityError: false
|
||||||
property bool firstTry: true
|
// property bool firstTry: true
|
||||||
|
|
||||||
Connections {
|
|
||||||
enabled: call != undefined && call != null
|
|
||||||
target: call && call.core
|
|
||||||
onStatusChanged: if (status === CallModel.CallStatusEnded) close()
|
|
||||||
function onSecurityUpdated() {
|
|
||||||
if (mainItem.isTokenVerified) {
|
|
||||||
close()
|
|
||||||
// mainItem.securityError = true
|
|
||||||
// } else close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function onTokenVerified() {
|
|
||||||
if (!mainItem.isTokenVerified) {
|
|
||||||
mainItem.securityError = true
|
|
||||||
} else close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Item {
|
background: Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -118,7 +100,7 @@ Dialog {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
z: 1
|
z: 1
|
||||||
width: mainItem.width
|
width: mainItem.width
|
||||||
height: parent.height - 87 * DefaultStyle.dp
|
height: parent.height - 85 * DefaultStyle.dp
|
||||||
x: parent.x
|
x: parent.x
|
||||||
y: parent.y + 85 * DefaultStyle.dp
|
y: parent.y + 85 * DefaultStyle.dp
|
||||||
color: DefaultStyle.grey_0
|
color: DefaultStyle.grey_0
|
||||||
|
|
@ -242,9 +224,10 @@ Dialog {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Layout.ColumnLayout {
|
Layout.ColumnLayout {
|
||||||
spacing: 0
|
|
||||||
Text {
|
|
||||||
visible: mainItem.securityError
|
visible: mainItem.securityError
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Text {
|
||||||
width: 303 * DefaultStyle.dp
|
width: 303 * DefaultStyle.dp
|
||||||
// Layout.Layout.preferredWidth: 343 * DefaultStyle.dp
|
// Layout.Layout.preferredWidth: 343 * DefaultStyle.dp
|
||||||
Layout.Layout.alignment: Qt.AlignHCenter
|
Layout.Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
@ -255,7 +238,6 @@ Dialog {
|
||||||
font.pixelSize: 14 * DefaultStyle.dp
|
font.pixelSize: 14 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
visible: mainItem.securityError
|
|
||||||
width: 303 * DefaultStyle.dp
|
width: 303 * DefaultStyle.dp
|
||||||
// Layout.Layout.preferredWidth: 343 * DefaultStyle.dp
|
// Layout.Layout.preferredWidth: 343 * DefaultStyle.dp
|
||||||
Layout.Layout.alignment: Qt.AlignHCenter
|
Layout.Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
@ -286,21 +268,6 @@ Dialog {
|
||||||
if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(" ")
|
if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(" ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Button {
|
|
||||||
Layout.Layout.preferredWidth: 247 * DefaultStyle.dp
|
|
||||||
visible: mainItem.securityError && mainItem.firstTry
|
|
||||||
text: qsTr("Réessayer")
|
|
||||||
color: DefaultStyle.danger_500main
|
|
||||||
inversedColors: true
|
|
||||||
leftPadding: 16 * DefaultStyle.dp
|
|
||||||
rightPadding: 16 * DefaultStyle.dp
|
|
||||||
topPadding: 10 * DefaultStyle.dp
|
|
||||||
bottomPadding: 10 * DefaultStyle.dp
|
|
||||||
onClicked: {
|
|
||||||
mainItem.firstTry = false
|
|
||||||
mainItem.securityError = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Button {
|
Button {
|
||||||
Layout.Layout.preferredWidth: 247 * DefaultStyle.dp
|
Layout.Layout.preferredWidth: 247 * DefaultStyle.dp
|
||||||
visible: mainItem.securityError
|
visible: mainItem.securityError
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,13 @@ ColumnLayout {
|
||||||
property FriendGui contact
|
property FriendGui contact
|
||||||
property ConferenceInfoGui conferenceInfo
|
property ConferenceInfoGui conferenceInfo
|
||||||
property bool isConference: conferenceInfo != undefined && conferenceInfo != null
|
property bool isConference: conferenceInfo != undefined && conferenceInfo != null
|
||||||
property string contactAddress: contact && contact.core.defaultAddress || ""
|
property string contactAddress: specificAddress != "" ? specificAddress : contact && contact.core.defaultAddress || ""
|
||||||
property string contactName: contact && contact.core.displayName || ""
|
property string contactName: contact && contact.core.displayName || ""
|
||||||
|
|
||||||
|
// Set this property to get the security informations
|
||||||
|
// for a specific address and not for the entire contact
|
||||||
|
property string specificAddress: ""
|
||||||
|
|
||||||
property alias buttonContent: rightButton.data
|
property alias buttonContent: rightButton.data
|
||||||
property alias detailContent: detailControl.data
|
property alias detailContent: detailControl.data
|
||||||
|
|
||||||
|
|
@ -63,8 +67,8 @@ ColumnLayout {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
width: 100 * DefaultStyle.dp
|
width: 100 * DefaultStyle.dp
|
||||||
height: 100 * DefaultStyle.dp
|
height: 100 * DefaultStyle.dp
|
||||||
contact: mainItem.contact || null
|
contact: mainItem.specificAddress == "" ? mainItem.contact : null
|
||||||
address: mainItem.conferenceInfo
|
_address: mainItem.conferenceInfo
|
||||||
? mainItem.conferenceInfo.core.subject
|
? mainItem.conferenceInfo.core.subject
|
||||||
: mainItem.contactAddress || mainItem.contactName
|
: mainItem.contactAddress || mainItem.contactName
|
||||||
}
|
}
|
||||||
|
|
@ -95,6 +99,19 @@ ColumnLayout {
|
||||||
capitalization: Font.Capitalize
|
capitalization: Font.Capitalize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Text {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
visible: mainItem.specificAddress != ""
|
||||||
|
text: mainItem.specificAddress
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
maximumLineCount: 1
|
||||||
|
font {
|
||||||
|
pixelSize: 12 * DefaultStyle.dp
|
||||||
|
weight: 300 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
Text {
|
Text {
|
||||||
property var mode : contact ? contact.core.consolidatedPresence : -1
|
property var mode : contact ? contact.core.consolidatedPresence : -1
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
@ -119,9 +136,6 @@ ColumnLayout {
|
||||||
weight: 300 * DefaultStyle.dp
|
weight: 300 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text {
|
|
||||||
// connection status
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -153,8 +167,8 @@ ColumnLayout {
|
||||||
button.icon.source: AppIcons.phone
|
button.icon.source: AppIcons.phone
|
||||||
label: qsTr("Appel")
|
label: qsTr("Appel")
|
||||||
button.onClicked: {
|
button.onClicked: {
|
||||||
if (mainItem.contact) mainWindow.startCallWithContact(mainItem.contact, false, mainItem)
|
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, false, mainItem)
|
||||||
else UtilsCpp.createCall(mainItem.contactAddress)
|
else UtilsCpp.createCall(mainItem.specificAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LabelButton {
|
LabelButton {
|
||||||
|
|
@ -176,8 +190,8 @@ ColumnLayout {
|
||||||
button.icon.source: AppIcons.videoCamera
|
button.icon.source: AppIcons.videoCamera
|
||||||
label: qsTr("Appel Video")
|
label: qsTr("Appel Video")
|
||||||
button.onClicked: {
|
button.onClicked: {
|
||||||
if (mainItem.contact) mainWindow.startCallWithContact(mainItem.contact, true, mainItem)
|
if (mainItem.specificAddress === "") mainWindow.startCallWithContact(mainItem.contact, true, mainItem)
|
||||||
else UtilsCpp.createCall(mainItem.contactAddress, {'localVideoEnabled': true})
|
else UtilsCpp.createCall(mainItem.specificAddress, {'localVideoEnabled': true})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ FocusScope{
|
||||||
Avatar {
|
Avatar {
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
address: modelData
|
_address: modelData
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
property var nameObj: UtilsCpp.getDisplayName(modelData)
|
property var nameObj: UtilsCpp.getDisplayName(modelData)
|
||||||
|
|
@ -167,7 +167,7 @@ FocusScope{
|
||||||
Avatar {
|
Avatar {
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
address: sipAddr.text
|
_address: sipAddr.text
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
Avatar {
|
Avatar {
|
||||||
id: historyAvatar
|
id: historyAvatar
|
||||||
address: modelData.core.remoteAddress
|
_address: modelData.core.remoteAddress
|
||||||
width: 45 * DefaultStyle.dp
|
width: 45 * DefaultStyle.dp
|
||||||
height: 45 * DefaultStyle.dp
|
height: 45 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
|
|
@ -647,7 +647,7 @@ AbstractMainPage {
|
||||||
property var contactObj: UtilsCpp.findFriendByAddress(contactAddress)
|
property var contactObj: UtilsCpp.findFriendByAddress(contactAddress)
|
||||||
contact: contactObj && contactObj.value || null
|
contact: contactObj && contactObj.value || null
|
||||||
conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null
|
conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null
|
||||||
contactAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || ""
|
specificAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || ""
|
||||||
contactName: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.displayName : ""
|
contactName: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.displayName : ""
|
||||||
|
|
||||||
buttonContent: PopupButton {
|
buttonContent: PopupButton {
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPanelContent: Item {
|
leftPanelContent: FocusScope {
|
||||||
id: leftPanel
|
id: leftPanel
|
||||||
property int leftMargin: 45 * DefaultStyle.dp
|
property int leftMargin: 45 * DefaultStyle.dp
|
||||||
property int rightMargin: 39 * DefaultStyle.dp
|
property int rightMargin: 39 * DefaultStyle.dp
|
||||||
|
|
@ -173,6 +173,7 @@ AbstractMainPage {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
|
id: createContactButton
|
||||||
background: Item {
|
background: Item {
|
||||||
}
|
}
|
||||||
icon.source: AppIcons.plusCircle
|
icon.source: AppIcons.plusCircle
|
||||||
|
|
@ -183,6 +184,7 @@ AbstractMainPage {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
mainItem.createContact("", "")
|
mainItem.createContact("", "")
|
||||||
}
|
}
|
||||||
|
KeyNavigation.down: searchBar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,8 +203,11 @@ AbstractMainPage {
|
||||||
Layout.topMargin: 18 * DefaultStyle.dp
|
Layout.topMargin: 18 * DefaultStyle.dp
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
placeholderText: qsTr("Rechercher un contact")
|
placeholderText: qsTr("Rechercher un contact")
|
||||||
|
KeyNavigation.up: createContactButton
|
||||||
|
KeyNavigation.down: favoriteList.contentHeight > 0 ? favoriteExpandButton : contactExpandButton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
Flickable {
|
Flickable {
|
||||||
id: listLayout
|
id: listLayout
|
||||||
contentWidth: width
|
contentWidth: width
|
||||||
|
|
@ -245,6 +250,7 @@ AbstractMainPage {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
|
id: favoriteExpandButton
|
||||||
background: Item{}
|
background: Item{}
|
||||||
icon.source: favoriteList.visible ? AppIcons.upArrow : AppIcons.downArrow
|
icon.source: favoriteList.visible ? AppIcons.upArrow : AppIcons.downArrow
|
||||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||||
|
|
@ -252,10 +258,13 @@ AbstractMainPage {
|
||||||
icon.width: 24 * DefaultStyle.dp
|
icon.width: 24 * DefaultStyle.dp
|
||||||
icon.height: 24 * DefaultStyle.dp
|
icon.height: 24 * DefaultStyle.dp
|
||||||
onClicked: favoriteList.visible = !favoriteList.visible
|
onClicked: favoriteList.visible = !favoriteList.visible
|
||||||
|
KeyNavigation.up: searchBar
|
||||||
|
KeyNavigation.down: favoriteList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ContactsList{
|
ContactsList{
|
||||||
id: favoriteList
|
id: favoriteList
|
||||||
|
onActiveFocusChanged: if (activeFocus) console.log("favorite list focus")
|
||||||
hoverEnabled: mainItem.leftPanelEnabled
|
hoverEnabled: mainItem.leftPanelEnabled
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: contentHeight
|
Layout.preferredHeight: contentHeight
|
||||||
|
|
@ -276,7 +285,7 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
visible: contactList.count > 0
|
visible: contactList.contentHeight > 0
|
||||||
onVisibleChanged: if (visible && !contactList.visible) contactList.visible = true
|
onVisibleChanged: if (visible && !contactList.visible) contactList.visible = true
|
||||||
Layout.leftMargin: leftPanel.leftMargin
|
Layout.leftMargin: leftPanel.leftMargin
|
||||||
Layout.rightMargin: leftPanel.rightMargin
|
Layout.rightMargin: leftPanel.rightMargin
|
||||||
|
|
@ -294,6 +303,7 @@ AbstractMainPage {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
|
id: contactExpandButton
|
||||||
background: Item{}
|
background: Item{}
|
||||||
icon.source: contactList.visible ? AppIcons.upArrow : AppIcons.downArrow
|
icon.source: contactList.visible ? AppIcons.upArrow : AppIcons.downArrow
|
||||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||||
|
|
@ -301,10 +311,13 @@ AbstractMainPage {
|
||||||
icon.width: 24 * DefaultStyle.dp
|
icon.width: 24 * DefaultStyle.dp
|
||||||
icon.height: 24 * DefaultStyle.dp
|
icon.height: 24 * DefaultStyle.dp
|
||||||
onClicked: contactList.visible = !contactList.visible
|
onClicked: contactList.visible = !contactList.visible
|
||||||
|
KeyNavigation.up: favoriteList.visible ? favoriteList : searchBar
|
||||||
|
KeyNavigation.down: contactList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ContactsList{
|
ContactsList{
|
||||||
id: contactList
|
id: contactList
|
||||||
|
onActiveFocusChanged: if (activeFocus) console.log("contact list focus")
|
||||||
onCountChanged: {
|
onCountChanged: {
|
||||||
if (initialFriendToDisplay.length !== 0) {
|
if (initialFriendToDisplay.length !== 0) {
|
||||||
if (selectContact(initialFriendToDisplay) != -1) initialFriendToDisplay = ""
|
if (selectContact(initialFriendToDisplay) != -1) initialFriendToDisplay = ""
|
||||||
|
|
@ -340,10 +353,8 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
ScrollBar {
|
ScrollBar {
|
||||||
id: contactsScrollbar
|
id: contactsScrollbar
|
||||||
anchors.right: listLayout.right
|
Layout.fillHeight: true
|
||||||
anchors.rightMargin: 8 * DefaultStyle.dp
|
Layout.rightMargin: 8 * DefaultStyle.dp
|
||||||
anchors.top: listLayout.top
|
|
||||||
anchors.bottom: listLayout.bottom
|
|
||||||
height: listLayout.height
|
height: listLayout.height
|
||||||
active: true
|
active: true
|
||||||
interactive: true
|
interactive: true
|
||||||
|
|
@ -351,6 +362,7 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: contactDetail
|
id: contactDetail
|
||||||
|
|
|
||||||
|
|
@ -93,20 +93,12 @@ AbstractMainPage {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPanelContent: Item {
|
leftPanelContent: Control.StackView {
|
||||||
|
id: leftPanelStackView
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 45 * DefaultStyle.dp
|
||||||
Control.StackView {
|
|
||||||
id: leftPanelStackView
|
|
||||||
initialItem: listLayout
|
initialItem: listLayout
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.leftMargin: 45 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -124,8 +116,6 @@ AbstractMainPage {
|
||||||
Component {
|
Component {
|
||||||
id: listLayout
|
id: listLayout
|
||||||
FocusScope{
|
FocusScope{
|
||||||
width: parent.width
|
|
||||||
height: listLayoutIn.implicitHeight
|
|
||||||
property string objectName: "listLayout"
|
property string objectName: "listLayout"
|
||||||
Control.StackView.onDeactivated: {
|
Control.StackView.onDeactivated: {
|
||||||
mainItem.selectedConference = null
|
mainItem.selectedConference = null
|
||||||
|
|
@ -171,11 +161,10 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
SearchBar {
|
SearchBar {
|
||||||
id: searchBar
|
id: searchBar
|
||||||
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 18 * DefaultStyle.dp
|
Layout.topMargin: 18 * DefaultStyle.dp
|
||||||
// Layout.fillWidth: true
|
Layout.rightMargin: 39 * DefaultStyle.dp
|
||||||
//Layout.topMargin: 18 * DefaultStyle.dp
|
|
||||||
placeholderText: qsTr("Rechercher une réunion")
|
placeholderText: qsTr("Rechercher une réunion")
|
||||||
Layout.preferredWidth: 331 * DefaultStyle.dp
|
|
||||||
KeyNavigation.up: conferenceList
|
KeyNavigation.up: conferenceList
|
||||||
KeyNavigation.down: conferenceList
|
KeyNavigation.down: conferenceList
|
||||||
}
|
}
|
||||||
|
|
@ -760,7 +749,7 @@ AbstractMainPage {
|
||||||
Avatar {
|
Avatar {
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
address: mainItem.selectedConference ? mainItem.selectedConference.core.organizerAddress : ""
|
_address: mainItem.selectedConference ? mainItem.selectedConference.core.organizerAddress : ""
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: mainItem.selectedConference ? mainItem.selectedConference.core.organizerName : ""
|
text: mainItem.selectedConference ? mainItem.selectedConference.core.organizerName : ""
|
||||||
|
|
@ -795,7 +784,7 @@ AbstractMainPage {
|
||||||
Avatar {
|
Avatar {
|
||||||
Layout.preferredWidth: 45 * DefaultStyle.dp
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
Layout.preferredHeight: 45 * DefaultStyle.dp
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
address: modelData.address
|
_address: modelData.address
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: modelData.displayName
|
text: modelData.displayName
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ Window{
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
height: 100
|
height: 100
|
||||||
width: height
|
width: height
|
||||||
address: 'sip:jul@toto.com'
|
_address: 'sip:jul@toto.com'
|
||||||
}
|
}
|
||||||
Loader{
|
Loader{
|
||||||
id: cameraLoader
|
id: cameraLoader
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ QtObject {
|
||||||
property string lockSimpleOpen: "image://internal/lock-simple-open.svg"
|
property string lockSimpleOpen: "image://internal/lock-simple-open.svg"
|
||||||
property string lockKey: "image://internal/lock-key.svg"
|
property string lockKey: "image://internal/lock-key.svg"
|
||||||
property string shieldWarning: "image://internal/shield-warning.svg"
|
property string shieldWarning: "image://internal/shield-warning.svg"
|
||||||
|
property string notTrusted: "image://internal/not-trusted.svg"
|
||||||
property string welcomeOpenSource: "image://internal/open_source.svg"
|
property string welcomeOpenSource: "image://internal/open_source.svg"
|
||||||
property string splashscreenLogo: "image://internal/splashscreen-logo.svg"
|
property string splashscreenLogo: "image://internal/splashscreen-logo.svg"
|
||||||
property string eyeHide: "image://internal/eye.svg"
|
property string eyeHide: "image://internal/eye.svg"
|
||||||
|
|
@ -64,6 +65,7 @@ QtObject {
|
||||||
property string speakerSlash: "image://internal/speaker-slash.svg"
|
property string speakerSlash: "image://internal/speaker-slash.svg"
|
||||||
property string trusted: "image://internal/trusted.svg"
|
property string trusted: "image://internal/trusted.svg"
|
||||||
property string trustedWhite: "image://internal/trusted-white.svg"
|
property string trustedWhite: "image://internal/trusted-white.svg"
|
||||||
|
property string trustedMask: "image://internal/trusted-mask.svg"
|
||||||
property string avatar: "image://internal/randomAvatar.png"
|
property string avatar: "image://internal/randomAvatar.png"
|
||||||
property string pause: "image://internal/pause.svg"
|
property string pause: "image://internal/pause.svg"
|
||||||
property string play: "image://internal/play.svg"
|
property string play: "image://internal/play.svg"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue