mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-17 05:55:23 +02:00
TroubleshootingSetting: Connection monitoring
Change-Id: Idf922df701cdf2efc2d167362dca021897d8e2e5
This commit is contained in:
parent
e55eaa5d8e
commit
6bff3c54f1
18 changed files with 880 additions and 5 deletions
|
@ -244,7 +244,8 @@ set(COMMON_SOURCES
|
||||||
${APP_SRC_DIR}/messageparser.cpp
|
${APP_SRC_DIR}/messageparser.cpp
|
||||||
${APP_SRC_DIR}/previewengine.cpp
|
${APP_SRC_DIR}/previewengine.cpp
|
||||||
${APP_SRC_DIR}/imagedownloader.cpp
|
${APP_SRC_DIR}/imagedownloader.cpp
|
||||||
${APP_SRC_DIR}/pluginversionmanager.cpp)
|
${APP_SRC_DIR}/pluginversionmanager.cpp
|
||||||
|
${APP_SRC_DIR}/connectioninfolistmodel.cpp)
|
||||||
|
|
||||||
set(COMMON_HEADERS
|
set(COMMON_HEADERS
|
||||||
${APP_SRC_DIR}/avatarimageprovider.h
|
${APP_SRC_DIR}/avatarimageprovider.h
|
||||||
|
@ -310,8 +311,8 @@ set(COMMON_HEADERS
|
||||||
${APP_SRC_DIR}/messageparser.h
|
${APP_SRC_DIR}/messageparser.h
|
||||||
${APP_SRC_DIR}/htmlparser.h
|
${APP_SRC_DIR}/htmlparser.h
|
||||||
${APP_SRC_DIR}/imagedownloader.h
|
${APP_SRC_DIR}/imagedownloader.h
|
||||||
${APP_SRC_DIR}/pluginversionmanager.h)
|
${APP_SRC_DIR}/pluginversionmanager.h
|
||||||
|
${APP_SRC_DIR}/connectioninfolistmodel.h)
|
||||||
|
|
||||||
# For libavutil/avframe.
|
# For libavutil/avframe.
|
||||||
set(LIBJAMI_CONTRIB_DIR "${DAEMON_DIR}/contrib")
|
set(LIBJAMI_CONTRIB_DIR "${DAEMON_DIR}/contrib")
|
||||||
|
|
12
resources/icons/Connected_Black_24dp.svg
Normal file
12
resources/icons/Connected_Black_24dp.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||||
|
<path id="noun-connection-5025318" d="M18,6.3c1.2,0,2.2-1,2.2-2.1C20.1,3,19.2,2,18,2c-1.2,0-2.2,1-2.2,2.1c0,0.5,0.2,1.1,0.6,1.5
|
||||||
|
l-3.3,3.8c-0.8-0.6-2-0.5-2.7,0.2L7.3,7.1c0.5-0.8,0.2-1.9-0.6-2.4C5.9,4.2,4.8,4.5,4.3,5.3C3.8,6.1,4,7.2,4.9,7.7
|
||||||
|
C5.6,8.1,6.4,8,7,7.5l3.1,2.5c-0.5,0.8-0.4,1.9,0.3,2.6l-2.9,2.9c-1.1-0.7-2.5-0.4-3.2,0.7c-0.7,1.1-0.4,2.5,0.7,3.2
|
||||||
|
c1.1,0.7,2.5,0.4,3.2-0.7c0.6-0.9,0.5-2.1-0.3-2.9l2.9-2.9c0.3,0.2,0.7,0.3,1.2,0.3c0,0,0.1,0,0.1,0l0.8,4.8
|
||||||
|
c-1.1,0.3-1.7,1.4-1.4,2.5c0.3,1.1,1.4,1.7,2.5,1.4c1.1-0.3,1.7-1.4,1.4-2.5c-0.3-0.9-1-1.4-1.9-1.4c0,0-0.1,0-0.1,0l-0.8-4.8
|
||||||
|
c0.4-0.1,0.7-0.3,0.9-0.6l3.6,2.7c-0.4,0.8-0.2,1.8,0.6,2.2c0.8,0.4,1.8,0.2,2.2-0.6c0.4-0.8,0.2-1.8-0.6-2.2
|
||||||
|
c-0.6-0.4-1.4-0.3-1.9,0.2l-3.6-2.7c0.2-0.3,0.3-0.7,0.3-1.1c0-0.5-0.2-1.1-0.6-1.5l3.3-3.8C17.1,6.2,17.5,6.3,18,6.3L18,6.3z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
23
resources/icons/Connecting_Black_24dp.svg
Normal file
23
resources/icons/Connecting_Black_24dp.svg
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||||
|
<g id="noun-waiting-3611673" transform="translate(-13.64 -30.48)">
|
||||||
|
<path id="Path_278" d="M25.9,34.5c0.5,0,0.8-0.4,0.8-0.8c0-0.5-0.4-0.8-0.8-0.8c-0.5,0-0.8,0.4-0.8,0.8c0,0.2,0.1,0.4,0.2,0.6
|
||||||
|
C25.4,34.4,25.6,34.5,25.9,34.5z"/>
|
||||||
|
<path id="Path_279" d="M32.7,36.9c0.4-0.4,0.4-1.1,0-1.5c-0.4-0.4-1.1-0.4-1.5,0c-0.4,0.4-0.4,1.1,0,1.5c0.2,0.2,0.5,0.3,0.8,0.3
|
||||||
|
C32.2,37.2,32.5,37.1,32.7,36.9z"/>
|
||||||
|
<path id="Path_280" d="M34.5,41c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.7,0,1.2-0.5,1.2-1.2c0-0.3-0.1-0.6-0.3-0.8
|
||||||
|
C35.1,41.1,34.8,41,34.5,41z"/>
|
||||||
|
<path id="Path_281" d="M31.9,47c-0.7,0-1.3,0.6-1.3,1.3c0,0.7,0.6,1.3,1.3,1.3c0.7,0,1.3-0.6,1.3-1.3c0-0.3-0.1-0.7-0.4-0.9
|
||||||
|
C32.6,47.1,32.3,47,31.9,47z"/>
|
||||||
|
<path id="Path_282" d="M25.9,49.4c-0.8,0-1.4,0.6-1.4,1.4c0,0.8,0.6,1.4,1.4,1.4c0.8,0,1.4-0.6,1.4-1.4c0-0.4-0.1-0.7-0.4-1
|
||||||
|
C26.6,49.5,26.2,49.4,25.9,49.4z"/>
|
||||||
|
<path id="Path_283" d="M18.7,47.2L18.7,47.2c-0.6,0.6-0.6,1.6,0,2.2c0.6,0.6,1.6,0.6,2.2,0c0.6-0.6,0.6-1.6,0-2.2
|
||||||
|
c-0.3-0.3-0.7-0.5-1.1-0.5C19.4,46.7,19,46.9,18.7,47.2z"/>
|
||||||
|
<path id="Path_284" d="M18.9,42.2c0-0.9-0.7-1.7-1.6-1.7s-1.7,0.7-1.7,1.6c0,0.9,0.7,1.7,1.6,1.7c0.4,0,0.9-0.2,1.2-0.5
|
||||||
|
C18.8,43,18.9,42.6,18.9,42.2z"/>
|
||||||
|
<path id="Path_285" d="M21.1,34.9c-0.7-0.3-1.5-0.1-1.9,0.6c-0.3,0.7-0.1,1.5,0.6,1.9c0.7,0.3,1.5,0.1,1.9-0.6
|
||||||
|
c0.1-0.2,0.2-0.5,0.1-0.7C21.8,35.5,21.5,35.1,21.1,34.9z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
228
src/app/connectioninfolistmodel.cpp
Normal file
228
src/app/connectioninfolistmodel.cpp
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "connectioninfolistmodel.h"
|
||||||
|
|
||||||
|
ConnectionInfoListModel::ConnectionInfoListModel(LRCInstance* instance, QObject* parent)
|
||||||
|
: AbstractListModelBase(parent)
|
||||||
|
{
|
||||||
|
lrcInstance_ = instance;
|
||||||
|
connect(lrcInstance_,
|
||||||
|
&LRCInstance::currentAccountIdChanged,
|
||||||
|
this,
|
||||||
|
&ConnectionInfoListModel::resetData);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ConnectionInfoListModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
return peerIds_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant
|
||||||
|
ConnectionInfoListModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
const auto accountId = lrcInstance_->get_currentAccountId();
|
||||||
|
|
||||||
|
if (accountId.isEmpty()) {
|
||||||
|
qWarning() << "ConnectionInfoListModel::data: accountId or peerID is empty";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
const auto peerId = peerIds_[index.row()];
|
||||||
|
const auto peerData = peerData_[peerId];
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case ConnectionInfoList::ChannelsMap: {
|
||||||
|
QVariantMap channelsMapMap;
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& device : peerData.keys()) {
|
||||||
|
QString channelsId = peerData[device]["id"].toString();
|
||||||
|
QVariantMap channelsMap;
|
||||||
|
const auto channelInfoList = lrcInstance_->getChannelList(accountId, channelsId);
|
||||||
|
for (const auto& channelInfo : channelInfoList) {
|
||||||
|
channelsMap.insert(channelInfo["id"], channelInfo["name"]);
|
||||||
|
}
|
||||||
|
channelsMapMap.insert(QString::number(i++), channelsMap);
|
||||||
|
}
|
||||||
|
return QVariant(channelsMapMap);
|
||||||
|
}
|
||||||
|
case ConnectionInfoList::ConnectionDatas: {
|
||||||
|
QString peerString;
|
||||||
|
peerString += "Peer:" + peerId;
|
||||||
|
for (const auto& device : peerData.keys()) {
|
||||||
|
peerString += "{";
|
||||||
|
peerString += "Device:" + device + ",";
|
||||||
|
peerString += "Status:" + peerData[device]["status"].toString() + ",";
|
||||||
|
peerString += "Channels:" + peerData[device]["channels"].toString() + ",";
|
||||||
|
peerString += "Remote Address" + peerData[device]["remoteAddress"].toString();
|
||||||
|
peerString += "}";
|
||||||
|
}
|
||||||
|
return peerString;
|
||||||
|
}
|
||||||
|
case ConnectionInfoList::PeerId:
|
||||||
|
return peerId;
|
||||||
|
case ConnectionInfoList::RemoteAddress: {
|
||||||
|
QVariantMap remoteAddressMap;
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& device : peerData.keys()) {
|
||||||
|
remoteAddressMap.insert(QString::number(i++), peerData[device]["remoteAddress"]);
|
||||||
|
}
|
||||||
|
return QVariant(remoteAddressMap);
|
||||||
|
}
|
||||||
|
case ConnectionInfoList::DeviceId: {
|
||||||
|
QVariantMap deviceMap;
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& device : peerData.keys()) {
|
||||||
|
deviceMap.insert(QString::number(i++), device);
|
||||||
|
}
|
||||||
|
return QVariant(deviceMap);
|
||||||
|
}
|
||||||
|
case ConnectionInfoList::Status: {
|
||||||
|
QVariantMap statusMap;
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& device : peerData.keys()) {
|
||||||
|
statusMap.insert(QString::number(i++), peerData[device]["status"]);
|
||||||
|
}
|
||||||
|
return QVariantMap(statusMap);
|
||||||
|
}
|
||||||
|
case ConnectionInfoList::Channels: {
|
||||||
|
QVariantMap channelsMap;
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& device : peerData.keys()) {
|
||||||
|
channelsMap.insert(QString::number(i++), peerData[device]["channels"]);
|
||||||
|
}
|
||||||
|
return QVariant(channelsMap);
|
||||||
|
}
|
||||||
|
case ConnectionInfoList::Count:
|
||||||
|
return peerData.size();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray>
|
||||||
|
ConnectionInfoListModel::roleNames() const
|
||||||
|
{
|
||||||
|
using namespace ConnectionInfoList;
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
#define X(role) roles[role] = #role;
|
||||||
|
CONNECTONINFO_ROLES
|
||||||
|
#undef X
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ConnectionInfoListModel::update()
|
||||||
|
{
|
||||||
|
const auto accountId = lrcInstance_->get_currentAccountId();
|
||||||
|
if (accountId.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
aggregateData();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::tuple<QVector<T>, QVector<T>>
|
||||||
|
getSetDiff(QVector<T> u, QVector<T> v)
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
QVector<T> a, r;
|
||||||
|
set_difference(v.begin(), v.end(), u.begin(), u.end(), inserter(a, a.begin()));
|
||||||
|
set_difference(u.begin(), u.end(), v.begin(), v.end(), inserter(r, r.begin()));
|
||||||
|
return {a, r};
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ConnectionInfoListModel::aggregateData()
|
||||||
|
{
|
||||||
|
const auto accountId = lrcInstance_->get_currentAccountId();
|
||||||
|
if (accountId.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectionInfoList_ = lrcInstance_->getConnectionList(accountId);
|
||||||
|
|
||||||
|
peerData_ = {};
|
||||||
|
|
||||||
|
QSet<QString> newPeerIds;
|
||||||
|
|
||||||
|
for (const auto& connectionInfo : connectionInfoList_) {
|
||||||
|
if (!connectionInfo["peer"].isEmpty()) {
|
||||||
|
newPeerIds.insert(connectionInfo["peer"]);
|
||||||
|
}
|
||||||
|
const auto channelInfoList = lrcInstance_->getChannelList(accountId, connectionInfo["id"]);
|
||||||
|
peerData_[connectionInfo["peer"]][connectionInfo["device"]] = {};
|
||||||
|
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["status"]
|
||||||
|
= connectionInfo["status"];
|
||||||
|
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["channels"] = channelInfoList
|
||||||
|
.size();
|
||||||
|
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["id"] = connectionInfo["id"];
|
||||||
|
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["remoteAddress"]
|
||||||
|
= connectionInfo["remoteAddress"];
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QString> oldVector;
|
||||||
|
for (const auto& peerId : peerIds_) {
|
||||||
|
oldVector << peerId;
|
||||||
|
}
|
||||||
|
QVector<QString> newVector;
|
||||||
|
for (const auto& peerId : newPeerIds) {
|
||||||
|
newVector << peerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(oldVector.begin(), oldVector.end());
|
||||||
|
std::sort(newVector.begin(), newVector.end());
|
||||||
|
|
||||||
|
QVector<QString> removed, added;
|
||||||
|
std::tie(added, removed) = getSetDiff(oldVector, newVector);
|
||||||
|
Q_FOREACH (const auto& key, added) {
|
||||||
|
auto index = std::distance(newVector.begin(),
|
||||||
|
std::find(newVector.begin(), newVector.end(), key));
|
||||||
|
beginInsertRows(QModelIndex(), index, index);
|
||||||
|
peerIds_.insert(index, key);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
Q_FOREACH (const auto& key, removed) {
|
||||||
|
auto index = std::distance(oldVector.begin(),
|
||||||
|
std::find(oldVector.begin(), oldVector.end(), key));
|
||||||
|
beginRemoveRows(QModelIndex(), index, index);
|
||||||
|
if (peerIds_.size() > index) {
|
||||||
|
peerIds_.remove(index);
|
||||||
|
} else {
|
||||||
|
qWarning() << "ConnectionInfoListModel::aggregateData: index out of range";
|
||||||
|
qWarning() << "index: " << index;
|
||||||
|
qWarning() << "key: " << key;
|
||||||
|
}
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: loop through all the peerIds_ and update the data for each one.
|
||||||
|
// This is not efficient, but it works.
|
||||||
|
Q_FOREACH (const auto& peerId, peerIds_) {
|
||||||
|
auto index = std::distance(peerIds_.begin(),
|
||||||
|
std::find(peerIds_.begin(), peerIds_.end(), peerId));
|
||||||
|
Q_EMIT dataChanged(this->index(index), this->index(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ConnectionInfoListModel::resetData()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
peerIds_.clear();
|
||||||
|
peerData_.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
64
src/app/connectioninfolistmodel.h
Normal file
64
src/app/connectioninfolistmodel.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "abstractlistmodelbase.h"
|
||||||
|
|
||||||
|
#define CONNECTONINFO_ROLES \
|
||||||
|
X(ConnectionDatas) \
|
||||||
|
X(ChannelsMap) \
|
||||||
|
X(PeerName) \
|
||||||
|
X(PeerId) \
|
||||||
|
X(DeviceId) \
|
||||||
|
X(Status) \
|
||||||
|
X(Channels) \
|
||||||
|
X(RemoteAddress) \
|
||||||
|
X(Count) // this is the number of connections (convenience)
|
||||||
|
|
||||||
|
namespace ConnectionInfoList {
|
||||||
|
Q_NAMESPACE
|
||||||
|
enum Role {
|
||||||
|
DummyRole = Qt::UserRole + 1,
|
||||||
|
#define X(role) role,
|
||||||
|
CONNECTONINFO_ROLES
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
Q_ENUM_NS(Role)
|
||||||
|
} // namespace ConnectionInfoList
|
||||||
|
|
||||||
|
class ConnectionInfoListModel : public AbstractListModelBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ConnectionInfoListModel(LRCInstance* instance, QObject* parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
Q_INVOKABLE void update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
using Role = ConnectionInfoList::Role;
|
||||||
|
|
||||||
|
VectorMapStringString connectionInfoList_;
|
||||||
|
|
||||||
|
QVector<QString> peerIds_;
|
||||||
|
QMap<QString, QMap<QString, QMap<QString, QVariant>>> peerData_;
|
||||||
|
void aggregateData();
|
||||||
|
void resetData();
|
||||||
|
};
|
|
@ -850,4 +850,16 @@ Item {
|
||||||
property string shiftEnter: qsTr("SHIFT+ENTER")
|
property string shiftEnter: qsTr("SHIFT+ENTER")
|
||||||
property string textFormattingDescription: qsTr("ENTER or SHIFT+ENTER to insert a new line")
|
property string textFormattingDescription: qsTr("ENTER or SHIFT+ENTER to insert a new line")
|
||||||
property string textFormatting: qsTr("Text formatting")
|
property string textFormatting: qsTr("Text formatting")
|
||||||
|
|
||||||
|
//Connection monitoring
|
||||||
|
property string connected: qsTr("Connected")
|
||||||
|
property string connectingTLS: qsTr("Connecting TLS")
|
||||||
|
property string connectingICE: qsTr("Connecting ICE")
|
||||||
|
property string connecting: qsTr("Connecting")
|
||||||
|
property string waiting: qsTr("Waiting")
|
||||||
|
property string contact: qsTr("Contact")
|
||||||
|
property string connection: qsTr("Connection")
|
||||||
|
property string channels: qsTr("Channels")
|
||||||
|
property string copyAllData: qsTr("Copy all data")
|
||||||
|
property string remote: qsTr("Remote: ")
|
||||||
}
|
}
|
||||||
|
|
|
@ -664,6 +664,11 @@ Item {
|
||||||
property color donationBackgroundColor: "#D5E4EF"
|
property color donationBackgroundColor: "#D5E4EF"
|
||||||
property string donationUrl: "https://jami.net/donate/"
|
property string donationUrl: "https://jami.net/donate/"
|
||||||
|
|
||||||
|
//Connection monitoring
|
||||||
|
property color connectionMonitoringTableColor1: "#f0efef"
|
||||||
|
property color connectionMonitoringTableColor2: "#f6f5f5"
|
||||||
|
property color connectionMonitoringHeaderColor: "#d1d1d1"
|
||||||
|
|
||||||
function setTheme(dark) {
|
function setTheme(dark) {
|
||||||
darkTheme = dark;
|
darkTheme = dark;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,16 @@
|
||||||
#include "contactadapter.h"
|
#include "contactadapter.h"
|
||||||
|
|
||||||
#include "lrcinstance.h"
|
#include "lrcinstance.h"
|
||||||
|
#include "qmlregister.h"
|
||||||
|
|
||||||
ContactAdapter::ContactAdapter(LRCInstance* instance, QObject* parent)
|
ContactAdapter::ContactAdapter(LRCInstance* instance, QObject* parent)
|
||||||
: QmlAdapterBase(instance, parent)
|
: QmlAdapterBase(instance, parent)
|
||||||
|
, connectionInfoListModel_(new ConnectionInfoListModel(lrcInstance_, this))
|
||||||
{
|
{
|
||||||
|
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS,
|
||||||
|
connectionInfoListModel_.get(),
|
||||||
|
"ConnectionInfoListModel");
|
||||||
|
|
||||||
selectableProxyModel_.reset(new SelectableProxyModel(this));
|
selectableProxyModel_.reset(new SelectableProxyModel(this));
|
||||||
if (lrcInstance_) {
|
if (lrcInstance_) {
|
||||||
connectSignals();
|
connectSignals();
|
||||||
|
@ -246,6 +252,12 @@ ContactAdapter::removeContact(const QString& peerUri, bool banContact)
|
||||||
accInfo.contactModel->removeContact(peerUri, banContact);
|
accInfo.contactModel->removeContact(peerUri, banContact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ContactAdapter::updateConnectionInfo()
|
||||||
|
{
|
||||||
|
connectionInfoListModel_->update();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ContactAdapter::connectSignals()
|
ContactAdapter::connectSignals()
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "qmladapterbase.h"
|
#include "qmladapterbase.h"
|
||||||
#include "smartlistmodel.h"
|
#include "smartlistmodel.h"
|
||||||
#include "conversationlistmodel.h"
|
#include "conversationlistmodel.h"
|
||||||
|
#include "connectioninfolistmodel.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
@ -90,6 +91,7 @@ public:
|
||||||
Q_INVOKABLE void setSearchFilter(const QString& filter);
|
Q_INVOKABLE void setSearchFilter(const QString& filter);
|
||||||
Q_INVOKABLE void contactSelected(int index);
|
Q_INVOKABLE void contactSelected(int index);
|
||||||
Q_INVOKABLE void removeContact(const QString& peerUri, bool banContact);
|
Q_INVOKABLE void removeContact(const QString& peerUri, bool banContact);
|
||||||
|
Q_INVOKABLE void updateConnectionInfo();
|
||||||
|
|
||||||
void connectSignals();
|
void connectSignals();
|
||||||
|
|
||||||
|
@ -104,6 +106,7 @@ private:
|
||||||
SmartListModel::Type listModeltype_;
|
SmartListModel::Type listModeltype_;
|
||||||
QScopedPointer<SmartListModel> smartListModel_;
|
QScopedPointer<SmartListModel> smartListModel_;
|
||||||
QScopedPointer<SelectableProxyModel> selectableProxyModel_;
|
QScopedPointer<SelectableProxyModel> selectableProxyModel_;
|
||||||
|
QScopedPointer<ConnectionInfoListModel> connectionInfoListModel_;
|
||||||
|
|
||||||
QStringList defaultModerators_;
|
QStringList defaultModerators_;
|
||||||
|
|
||||||
|
|
|
@ -458,3 +458,15 @@ LRCInstance::set_selectedConvUid(QString selectedConvUid)
|
||||||
Q_EMIT selectedConvUidChanged();
|
Q_EMIT selectedConvUidChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VectorMapStringString
|
||||||
|
LRCInstance::getConnectionList(const QString& accountId, const QString& uid)
|
||||||
|
{
|
||||||
|
return Lrc::getConnectionList(accountId, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorMapStringString
|
||||||
|
LRCInstance::getChannelList(const QString& accountId, const QString& uid)
|
||||||
|
{
|
||||||
|
return Lrc::getChannelList(accountId, uid);
|
||||||
|
}
|
|
@ -135,6 +135,10 @@ public:
|
||||||
return debugMode_;
|
return debugMode_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VectorMapStringString getConnectionList(const QString& accountId, const QString& uid = {});
|
||||||
|
|
||||||
|
VectorMapStringString getChannelList(const QString& accountId, const QString& uid = {});
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void accountListChanged();
|
void accountListChanged();
|
||||||
void selectedConvUidChanged();
|
void selectedConvUidChanged();
|
||||||
|
|
60
src/app/settingsview/components/ChannelsPopup.qml
Normal file
60
src/app/settingsview/components/ChannelsPopup.qml
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import net.jami.Models 1.1
|
||||||
|
import net.jami.Adapters 1.1
|
||||||
|
import net.jami.Constants 1.1
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: popup
|
||||||
|
width: textComponent.contentWidth + 40 < popup.maxWidth - 20 ? textComponent.contentWidth + 40 : popup.maxWidth - 20
|
||||||
|
height: textComponent.contentHeight + 40 < 350 ? textComponent.contentHeight + 40 : 350
|
||||||
|
property string text: ""
|
||||||
|
property int maxWidth: 0
|
||||||
|
x: -1 * (popup.width - 20)
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
anchors.fill: parent
|
||||||
|
contentHeight: textComponent.contentHeight + 10
|
||||||
|
contentWidth: textComponent.contentWidth + 20
|
||||||
|
clip: true
|
||||||
|
ScrollBar.vertical: ScrollBar {
|
||||||
|
active: contentHeight > height
|
||||||
|
}
|
||||||
|
ScrollBar.horizontal: ScrollBar {
|
||||||
|
active: contentWidth > width
|
||||||
|
}
|
||||||
|
contentX: 10
|
||||||
|
contentY: 10
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: textComponent
|
||||||
|
width: popup.maxWidth - 20
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
text: popup.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
381
src/app/settingsview/components/ConnectionMonitoringTable.qml
Normal file
381
src/app/settingsview/components/ConnectionMonitoringTable.qml
Normal file
|
@ -0,0 +1,381 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import net.jami.Adapters 1.1
|
||||||
|
import net.jami.Constants 1.1
|
||||||
|
import net.jami.Enums 1.1
|
||||||
|
import net.jami.Models 1.1
|
||||||
|
import "../../commoncomponents"
|
||||||
|
import "../js/logviewwindowcreation.js" as LogViewWindowCreation
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listview
|
||||||
|
height: contentItem.childrenRect.height
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 10
|
||||||
|
|
||||||
|
spacing: 5
|
||||||
|
cacheBuffer: 10
|
||||||
|
|
||||||
|
property int rota: 0
|
||||||
|
|
||||||
|
header: Rectangle {
|
||||||
|
height: 55
|
||||||
|
width: connectionMonitoringTable.width
|
||||||
|
Rectangle {
|
||||||
|
color: JamiTheme.connectionMonitoringHeaderColor
|
||||||
|
anchors.top: parent.top
|
||||||
|
height: 50
|
||||||
|
width: connectionMonitoringTable.width
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
Rectangle {
|
||||||
|
id: profile
|
||||||
|
height: 50
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
Layout.preferredWidth: 210
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
Text {
|
||||||
|
id: textImage
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: JamiStrings.contact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: device
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 50
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
Text {
|
||||||
|
id: deviceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: JamiStrings.device
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: connection
|
||||||
|
width: 130
|
||||||
|
height: 50
|
||||||
|
radius: 5
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
Text {
|
||||||
|
id: connectionText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
text: JamiStrings.connection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: channel
|
||||||
|
height: 50
|
||||||
|
width: 70
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
Text {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: JamiStrings.channels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model: ConnectionInfoListModel
|
||||||
|
Timer {
|
||||||
|
interval: 1000
|
||||||
|
running: root.visible
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
ContactAdapter.updateConnectionInfo();
|
||||||
|
listview.rota = listview.rota + 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
id: delegate
|
||||||
|
height: Count == 0 ? 0 : 10 + 40 * Count
|
||||||
|
width: connectionMonitoringTable.width
|
||||||
|
color: index % 2 === 0 ? JamiTheme.connectionMonitoringTableColor1 : JamiTheme.connectionMonitoringTableColor2
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listView2
|
||||||
|
height: 40 * Count
|
||||||
|
|
||||||
|
anchors.top: delegate.top
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
model: Count
|
||||||
|
|
||||||
|
delegate: RowLayout {
|
||||||
|
id: rowLayoutDelegate
|
||||||
|
height: 40
|
||||||
|
width: connectionMonitoringTable.width
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: profile
|
||||||
|
height: 50
|
||||||
|
Layout.leftMargin: 5
|
||||||
|
Layout.preferredWidth: 210
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
Avatar {
|
||||||
|
id: avatar
|
||||||
|
visible: index == 0
|
||||||
|
anchors.left: parent.left
|
||||||
|
height: 40
|
||||||
|
width: 40
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
imageId: PeerId
|
||||||
|
mode: Avatar.Mode.Contact
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: usernameRect
|
||||||
|
anchors.left: avatar.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: profile.width - 50
|
||||||
|
height: 40
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: usernameRect2
|
||||||
|
visible: index == 0
|
||||||
|
width: profile.width - 50
|
||||||
|
height: 20
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: usernameText
|
||||||
|
text: UtilsAdapter.getBestNameForUri(CurrentAccount.id, PeerId)
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: profile.width - 50
|
||||||
|
height: 20
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.top: usernameRect2.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
visible: usernameRect2.visible && (UtilsAdapter.getBestIdForUri(CurrentAccount.id, PeerId) != UtilsAdapter.getBestNameForUri(CurrentAccount.id, PeerId))
|
||||||
|
color: JamiTheme.transparentColor
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: idText
|
||||||
|
anchors.fill: parent
|
||||||
|
text: UtilsAdapter.getBestIdForUri(CurrentAccount.id, PeerId)
|
||||||
|
font.pixelSize: 12
|
||||||
|
font.underline: usernameText.font.underline
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
usernameText.font.underline = true;
|
||||||
|
tooltipContact.text = JamiStrings.copyAllData;
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
usernameText.font.underline = false;
|
||||||
|
tooltipContact.text = JamiStrings.copyAllData;
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolTip {
|
||||||
|
id: tooltipContact
|
||||||
|
visible: usernameText.font.underline
|
||||||
|
text: JamiStrings.copyAllData
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
tooltipContact.text = JamiStrings.logsViewCopied;
|
||||||
|
UtilsAdapter.setClipboardText(ConnectionDatas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
height: 40
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: delegate.color
|
||||||
|
Text {
|
||||||
|
id: delegateDeviceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
text: {
|
||||||
|
if (DeviceId[index] != undefined) {
|
||||||
|
return DeviceId[index];
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
width: parent.width - 10
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
delegateDeviceText.font.underline = true;
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
delegateDeviceText.font.underline = false;
|
||||||
|
tooltipDevice.text = delegateDeviceText.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolTip {
|
||||||
|
id: tooltipDevice
|
||||||
|
visible: delegateDeviceText.font.underline
|
||||||
|
text: delegateDeviceText.text
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
tooltipDevice.text = delegateDeviceText.text + " (" + JamiStrings.logsViewCopied + ")";
|
||||||
|
UtilsAdapter.setClipboardText(delegateDeviceText.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: connectionRectangle
|
||||||
|
color: delegate.color
|
||||||
|
height: 40
|
||||||
|
Layout.preferredWidth: 130
|
||||||
|
property var status: Status[index]
|
||||||
|
ResponsiveImage {
|
||||||
|
id: connectionImage
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
rotation: connectionRectangle.status == 0 ? 0 : listview.rota
|
||||||
|
source: {
|
||||||
|
if (connectionRectangle.status == 0) {
|
||||||
|
return JamiResources.connected_black_24dp_svg;
|
||||||
|
} else {
|
||||||
|
return JamiResources.connecting_black_24dp_svg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color: {
|
||||||
|
if (connectionRectangle.status == 0) {
|
||||||
|
return "#009c7f";
|
||||||
|
} else {
|
||||||
|
if (connectionRectangle.status == 4) {
|
||||||
|
return "red";
|
||||||
|
} else {
|
||||||
|
return "#ff8100";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
id: connectionText
|
||||||
|
anchors.left: connectionImage.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
text: if (connectionRectangle.status == 0) {
|
||||||
|
return JamiStrings.connected;
|
||||||
|
} else {
|
||||||
|
if (connectionRectangle.status == 1) {
|
||||||
|
return JamiStrings.connectingTLS;
|
||||||
|
} else {
|
||||||
|
if (connectionRectangle.status == 2) {
|
||||||
|
return JamiStrings.connectingICE;
|
||||||
|
} else {
|
||||||
|
if (connectionRectangle.status == 3) {
|
||||||
|
return JamiStrings.connecting;
|
||||||
|
} else {
|
||||||
|
return JamiStrings.waiting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color: connectionImage.color
|
||||||
|
property var tooltipText: JamiStrings.remote + RemoteAddress[index]
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
connectionText.font.underline = true;
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
connectionText.font.underline = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolTip {
|
||||||
|
visible: connectionText.font.underline
|
||||||
|
text: connectionText.tooltipText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: channelDelegateRectangle
|
||||||
|
height: 40
|
||||||
|
Layout.preferredWidth: 70
|
||||||
|
color: delegate.color
|
||||||
|
Text {
|
||||||
|
id: channelText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.left: parent.left
|
||||||
|
text: {
|
||||||
|
if (Channels[index] != undefined) {
|
||||||
|
return Channels[index];
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onExited: {
|
||||||
|
channelText.font.underline = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onEntered: {
|
||||||
|
channelText.font.underline = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var output = "";
|
||||||
|
var channelMap = ChannelsMap[index];
|
||||||
|
for (var key in channelMap) {
|
||||||
|
var value = channelMap[key];
|
||||||
|
var keyHexa = parseInt(key, 16).toString();
|
||||||
|
output += keyHexa + " : " + value + "\n";
|
||||||
|
}
|
||||||
|
viewCoordinator.presentDialog(parent, "settingsview/components/ChannelsPopup.qml", {
|
||||||
|
"text": output,
|
||||||
|
"maxWidth": connectionMonitoringTable.width
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ JamiSplitView {
|
||||||
id: root
|
id: root
|
||||||
required property Item flickableContent
|
required property Item flickableContent
|
||||||
property real contentFlickableWidth: Math.min(JamiTheme.maximumWidthSettingsView, settingsPage.width - 2 * JamiTheme.preferredSettingsMarginSize)
|
property real contentFlickableWidth: Math.min(JamiTheme.maximumWidthSettingsView, settingsPage.width - 2 * JamiTheme.preferredSettingsMarginSize)
|
||||||
|
property real tableWidth: Math.min(JamiTheme.maximumWidthSettingsView * 2, settingsPage.width - 2 * JamiTheme.preferredSettingsMarginSize)
|
||||||
property alias title: settingsPage.title
|
property alias title: settingsPage.title
|
||||||
property color backgroundColor: JamiTheme.secondaryBackgroundColor
|
property color backgroundColor: JamiTheme.secondaryBackgroundColor
|
||||||
property alias pageContainer: settingsPage
|
property alias pageContainer: settingsPage
|
||||||
|
|
|
@ -29,11 +29,18 @@ import "../js/logviewwindowcreation.js" as LogViewWindowCreation
|
||||||
SettingsPageBase {
|
SettingsPageBase {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
readonly property string baseProviderPrefix: 'image://avatarImage'
|
||||||
|
|
||||||
|
property string typePrefix: 'contact'
|
||||||
|
property string divider: '_'
|
||||||
|
|
||||||
property int itemWidth
|
property int itemWidth
|
||||||
|
|
||||||
title: JamiStrings.troubleshootTitle
|
title: JamiStrings.troubleshootTitle
|
||||||
|
|
||||||
flickableContent: ColumnLayout {
|
flickableContent: Column {
|
||||||
id: troubleshootSettingsColumnLayout
|
id: troubleshootSettingsColumnLayout
|
||||||
|
|
||||||
width: contentFlickableWidth
|
width: contentFlickableWidth
|
||||||
|
@ -42,7 +49,7 @@ SettingsPageBase {
|
||||||
anchors.leftMargin: JamiTheme.preferredSettingsMarginSize
|
anchors.leftMargin: JamiTheme.preferredSettingsMarginSize
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
id: rawLayout
|
||||||
Text {
|
Text {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 30
|
Layout.preferredHeight: 30
|
||||||
|
@ -85,5 +92,15 @@ SettingsPageBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: connectionMonitoringTable
|
||||||
|
height: listview.childrenRect.height + 60
|
||||||
|
width: tableWidth
|
||||||
|
|
||||||
|
ConnectionMonitoringTable {
|
||||||
|
id: listview
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,16 @@ public:
|
||||||
*/
|
*/
|
||||||
static VectorString getConferences(const QString& accountId = "");
|
static VectorString getConferences(const QString& accountId = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get connection list from daemon
|
||||||
|
*/
|
||||||
|
static VectorMapStringString getConnectionList(const QString& accountId, const QString& uid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get channel list from daemon
|
||||||
|
*/
|
||||||
|
static VectorMapStringString getChannelList(const QString& accountId, const QString& uid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preference
|
* Preference
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -211,6 +211,18 @@ Lrc::getConferences(const QString& accountId)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VectorMapStringString
|
||||||
|
Lrc::getConnectionList(const QString& accountId, const QString& uid)
|
||||||
|
{
|
||||||
|
return ConfigurationManager::instance().getConnectionList(accountId, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorMapStringString
|
||||||
|
Lrc::getChannelList(const QString& accountId, const QString& uid)
|
||||||
|
{
|
||||||
|
return ConfigurationManager::instance().getChannelList(accountId, uid);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isFinished(const QString& callState)
|
isFinished(const QString& callState)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1016,6 +1016,24 @@ public Q_SLOTS: // METHODS
|
||||||
libjami::setAllModerators(accountID.toStdString(), allModerators);
|
libjami::setAllModerators(accountID.toStdString(), allModerators);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VectorMapStringString getConnectionList(const QString& accountId, const QString& uid)
|
||||||
|
{
|
||||||
|
VectorMapStringString temp;
|
||||||
|
for (auto x : libjami::getConnectionList(accountId.toStdString(), uid.toStdString())) {
|
||||||
|
temp.push_back(convertMap(x));
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorMapStringString getChannelList(const QString& accountId, const QString& uid)
|
||||||
|
{
|
||||||
|
VectorMapStringString temp;
|
||||||
|
for (auto x : libjami::getChannelList(accountId.toStdString(), uid.toStdString())) {
|
||||||
|
temp.push_back(convertMap(x));
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
bool isAllModerators(const QString& accountID)
|
bool isAllModerators(const QString& accountID)
|
||||||
{
|
{
|
||||||
return libjami::isAllModerators(accountID.toStdString());
|
return libjami::isAllModerators(accountID.toStdString());
|
||||||
|
|
Loading…
Add table
Reference in a new issue