mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-23 06:38:07 +00:00
feat(app): many changes:
- use vcard of Contact in qml - remove `sipAddress` attribute of Contact - refactoring...
This commit is contained in:
parent
eec251eaed
commit
08fbc20c97
16 changed files with 84 additions and 79 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 633e151d8a1775e8b4f717158d12bc0c0957c4ed
|
||||
Subproject commit eaeab2d665423e1fdbf2f59c2ae8da6c3c89c8fa
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 7b70508d9591c794ec42a80438a11f067f665994
|
||||
Subproject commit e816a335cd1693cdbbde27a69143e1570058ed5f
|
||||
|
|
@ -65,12 +65,12 @@ QString VcardModel::getAvatar () const {
|
|||
);
|
||||
}
|
||||
|
||||
void VcardModel::setAvatar (const QString &path) {
|
||||
bool VcardModel::setAvatar (const QString &path) {
|
||||
// 1. Try to copy photo in avatars folder.
|
||||
QFile file(path);
|
||||
|
||||
if (!file.exists() || QImageReader::imageFormat(path).size() == 0)
|
||||
return;
|
||||
return false;
|
||||
|
||||
QFileInfo info(file);
|
||||
QString uuid = QUuid::createUuid().toString();
|
||||
|
|
@ -81,7 +81,7 @@ void VcardModel::setAvatar (const QString &path) {
|
|||
QString dest = ::Utils::linphoneStringToQString(Database::getAvatarsPath()) + file_id;
|
||||
|
||||
if (!file.copy(dest))
|
||||
return;
|
||||
return false;
|
||||
|
||||
qInfo() << QStringLiteral("Update avatar of `%1`. (path=%2)").arg(getUsername()).arg(dest);
|
||||
|
||||
|
|
@ -112,9 +112,12 @@ void VcardModel::setAvatar (const QString &path) {
|
|||
shared_ptr<belcard::BelCardPhoto> photo =
|
||||
belcard::BelCardGeneric::create<belcard::BelCardPhoto>();
|
||||
photo->setValue(VCARD_SCHEME + ::Utils::qStringToLinphoneString(file_id));
|
||||
belcard->addPhoto(photo);
|
||||
|
||||
if (!belcard->addPhoto(photo))
|
||||
return false;
|
||||
|
||||
emit vcardUpdated();
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -135,7 +138,7 @@ QVariantMap VcardModel::getAddress () const {
|
|||
return map;
|
||||
}
|
||||
|
||||
void VcardModel::setAddress (const QVariantMap &address) {
|
||||
bool VcardModel::setAddress (const QVariantMap &address) {
|
||||
shared_ptr<belcard::BelCard> belcard = m_vcard->getBelcard();
|
||||
list<shared_ptr<belcard::BelCardAddress> > addresses = belcard->getAddresses();
|
||||
|
||||
|
|
@ -150,9 +153,11 @@ void VcardModel::setAddress (const QVariantMap &address) {
|
|||
belcard_address->setPostalCode(::Utils::qStringToLinphoneString(address["postalCode"].toString()));
|
||||
belcard_address->setCountry(::Utils::qStringToLinphoneString(address["country"].toString()));
|
||||
|
||||
belcard->addAddress(belcard_address);
|
||||
if (!belcard->addAddress(belcard_address))
|
||||
return false;
|
||||
|
||||
emit vcardUpdated();
|
||||
return true;
|
||||
}
|
||||
|
||||
QVariantList VcardModel::getSipAddresses () const {
|
||||
|
|
@ -165,11 +170,19 @@ QVariantList VcardModel::getSipAddresses () const {
|
|||
}
|
||||
|
||||
bool VcardModel::addSipAddress (const QString &sip_address) {
|
||||
shared_ptr<linphone::Address> address = CoreManager::getInstance()->getCore()->createAddress(
|
||||
::Utils::qStringToLinphoneString(sip_address)
|
||||
);
|
||||
|
||||
if (!address) {
|
||||
qWarning() << QStringLiteral("Unable to add invalid sip address: `%1`.").arg(sip_address);
|
||||
return false;
|
||||
}
|
||||
|
||||
qInfo() << QStringLiteral("Add new sip address: `%1`.").arg(sip_address);
|
||||
m_vcard->addSipAddress(::Utils::qStringToLinphoneString(sip_address));
|
||||
m_vcard->addSipAddress(address->asStringUriOnly());
|
||||
|
||||
emit vcardUpdated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -227,10 +240,11 @@ bool VcardModel::addCompany (const QString &company) {
|
|||
value->setValue(::Utils::qStringToLinphoneString(company));
|
||||
|
||||
qInfo() << QStringLiteral("Add new company: `%1`.").arg(company);
|
||||
belcard->addRole(value);
|
||||
|
||||
if (!belcard->addRole(value))
|
||||
return false;
|
||||
|
||||
emit vcardUpdated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -276,10 +290,11 @@ bool VcardModel::addEmail (const QString &email) {
|
|||
value->setValue(::Utils::qStringToLinphoneString(email));
|
||||
|
||||
qInfo() << QStringLiteral("Add new email: `%1`.").arg(email);
|
||||
belcard->addEmail(value);
|
||||
|
||||
if (!belcard->addEmail(value))
|
||||
return false;
|
||||
|
||||
emit vcardUpdated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -324,10 +339,11 @@ bool VcardModel::addUrl (const QString &url) {
|
|||
value->setValue(::Utils::qStringToLinphoneString(url));
|
||||
|
||||
qInfo() << QStringLiteral("Add new url: `%1`.").arg(url);
|
||||
belcard->addURL(value);
|
||||
|
||||
if (!belcard->addURL(value))
|
||||
return false;
|
||||
|
||||
emit vcardUpdated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,10 +49,10 @@ private:
|
|||
void setUsername (const QString &username);
|
||||
|
||||
QString getAvatar () const;
|
||||
void setAvatar (const QString &path);
|
||||
bool setAvatar (const QString &path);
|
||||
|
||||
QVariantMap getAddress () const;
|
||||
void setAddress (const QVariantMap &address);
|
||||
bool setAddress (const QVariantMap &address);
|
||||
|
||||
QVariantList getSipAddresses () const;
|
||||
QVariantList getCompanies () const;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
Item {
|
||||
id: item
|
||||
|
|
@ -58,6 +58,6 @@ Item {
|
|||
samplerName: 'mask'
|
||||
}
|
||||
|
||||
radius: parent.width / 2
|
||||
radius: width / 2
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Linphone 1.0
|
|||
import Linphone.Styles 1.0
|
||||
import Utils 1.0
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
Item {
|
||||
id: avatar
|
||||
|
|
@ -17,7 +17,7 @@ Item {
|
|||
|
||||
property var _initialsRegex: /^\s*([^\s\.]+)(?:[\s\.]+([^\s\.]+))?/
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function isLoaded () {
|
||||
return roundedImage.status === Image.Ready
|
||||
|
|
@ -28,7 +28,7 @@ Item {
|
|||
|
||||
Utils.assert(
|
||||
result != null,
|
||||
'Unable to get initials of: \'' + username + '\''
|
||||
'Unable to get initials of: `' + username + '`.'
|
||||
)
|
||||
|
||||
return result[1].charAt(0).toUpperCase() + (
|
||||
|
|
@ -38,7 +38,7 @@ Item {
|
|||
)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
RoundedImage {
|
||||
id: roundedImage
|
||||
|
|
|
|||
|
|
@ -5,9 +5,8 @@ import Common 1.0
|
|||
import Linphone 1.0
|
||||
import LinphoneUtils 1.0
|
||||
import Linphone.Styles 1.0
|
||||
import Utils 1.0
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
Rectangle {
|
||||
id: item
|
||||
|
|
@ -15,12 +14,8 @@ Rectangle {
|
|||
property alias actions: actionBar.data
|
||||
property alias sipAddressColor: description.sipAddressColor
|
||||
property alias usernameColor: description.usernameColor
|
||||
|
||||
// Can be a contact object or just a sip address.
|
||||
property var contact
|
||||
|
||||
// Override contact.sipAddress if used.
|
||||
property var sipAddress
|
||||
property string sipAddress
|
||||
property var _contact: ContactsListModel.mapSipAddressToContact(sipAddress)
|
||||
|
||||
color: 'transparent' // No color by default.
|
||||
height: ContactStyle.height
|
||||
|
|
@ -38,9 +33,9 @@ Rectangle {
|
|||
|
||||
Layout.preferredHeight: ContactStyle.contentHeight
|
||||
Layout.preferredWidth: ContactStyle.contentHeight
|
||||
image: contact.avatar
|
||||
presenceLevel: contact.presenceLevel || Presence.White
|
||||
username: LinphoneUtils.getContactUsername(contact)
|
||||
image: _contact && _contact.vcard.avatar
|
||||
presenceLevel: _contact ? contact.presenceLevel : Presence.White
|
||||
username: LinphoneUtils.getContactUsername(_contact || sipAddress)
|
||||
}
|
||||
|
||||
ContactDescription {
|
||||
|
|
@ -48,9 +43,7 @@ Rectangle {
|
|||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
sipAddress: Utils.isString(contact)
|
||||
? contact
|
||||
: item.sipAddress || contact.sipAddress
|
||||
sipAddress: item.sipAddress
|
||||
username: avatar.username
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import QtQuick 2.7
|
|||
|
||||
import Linphone.Styles 1.0
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
Column {
|
||||
property alias sipAddress: sipAddress.text
|
||||
|
|
@ -11,7 +11,6 @@ Column {
|
|||
property color usernameColor: ContactDescriptionStyle.username.color
|
||||
property int horizontalTextAlignment
|
||||
|
||||
// Username.
|
||||
Text {
|
||||
id: username
|
||||
|
||||
|
|
@ -25,7 +24,6 @@ Column {
|
|||
width: parent.width
|
||||
}
|
||||
|
||||
// Sip address.
|
||||
Text {
|
||||
id: sipAddress
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ SearchBox {
|
|||
id: searchBox
|
||||
|
||||
delegate: Contact {
|
||||
contact: $contact
|
||||
// contact: $contact
|
||||
width: parent.width
|
||||
|
||||
actions: [
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ ColumnLayout {
|
|||
? TimelineStyle.contact.backgroundColor.a
|
||||
: TimelineStyle.contact.backgroundColor.b
|
||||
)
|
||||
contact: parent.contact
|
||||
sipAddress: $timelineEntry.sipAddresses
|
||||
sipAddressColor: view.currentIndex === index
|
||||
? TimelineStyle.contact.sipAddress.color.selected
|
||||
|
|
@ -100,7 +99,8 @@ ColumnLayout {
|
|||
anchors.fill: parent
|
||||
sourceComponent: TooltipArea {
|
||||
text: $timelineEntry.timestamp.toLocaleString(
|
||||
Qt.locale(App.locale()), Locale.ShortFormat
|
||||
Qt.locale(App.locale()),
|
||||
Locale.ShortFormat
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@
|
|||
function getContactUsername (contact) {
|
||||
return Utils.isString(contact)
|
||||
? contact.substring(4, contact.indexOf('@')) // 4 = length("sip:")
|
||||
: contact.username
|
||||
: contact.vcard.username
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// ===================================================================
|
||||
// =============================================================================
|
||||
// Library to deal with URI.
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
.pragma library
|
||||
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
// Not standard but helpful.
|
||||
var SUPPORTS_URL = true
|
||||
|
||||
// Level 0. ----------------------------------------------------------
|
||||
// Level 0. --------------------------------------------------------------------
|
||||
|
||||
var URI_PCT_ENCODED = '%[A-Fa-f\\d]{2}'
|
||||
var URI_PORT = '\\d*'
|
||||
|
|
@ -18,7 +18,7 @@ var URI_SCHEME = '[a-zA-Z][\\w+\-\.]*'
|
|||
var URI_SUB_DELIMS = '[!$&\'()*+,;=]'
|
||||
var URI_UNRESERVED = '[\\w\-\._~]'
|
||||
|
||||
// Level 1. ----------------------------------------------------------
|
||||
// Level 1. --------------------------------------------------------------------
|
||||
|
||||
var URI_HOST = '(' +
|
||||
'(' +
|
||||
|
|
@ -42,7 +42,7 @@ var URI_USERINFO = '(?:' +
|
|||
'|' + ':' +
|
||||
')*'
|
||||
|
||||
// Level 2. ----------------------------------------------------------
|
||||
// Level 2. --------------------------------------------------------------------
|
||||
|
||||
var URI_AUTHORITY = '(?:' + URI_USERINFO + '@' + ')?' +
|
||||
URI_HOST +
|
||||
|
|
@ -61,7 +61,7 @@ var URI_QUERY = '(?:' +
|
|||
var URI_SEGMENT = URI_PCHAR + '*'
|
||||
var URI_SEGMENT_NZ = URI_PCHAR + '+'
|
||||
|
||||
// Level 3. ----------------------------------------------------------
|
||||
// Level 3. --------------------------------------------------------------------
|
||||
|
||||
var URI_PATH_ABEMPTY = '(?:' + '/' + URI_SEGMENT + ')*'
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ var URI_PATH_ABSOLUTE = '/' +
|
|||
var URI_PATH_ROOTLESS =
|
||||
URI_SEGMENT_NZ + '(?:' + '/' + URI_SEGMENT + ')*'
|
||||
|
||||
// Level 4. ----------------------------------------------------------
|
||||
// Level 4. --------------------------------------------------------------------
|
||||
|
||||
// `path-empty` not used.
|
||||
var URI_HIER_PART = '(?:' +
|
||||
|
|
@ -80,7 +80,7 @@ var URI_HIER_PART = '(?:' +
|
|||
'|' + URI_PATH_ROOTLESS +
|
||||
')'
|
||||
|
||||
// Level 5. ----------------------------------------------------------
|
||||
// Level 5. --------------------------------------------------------------------
|
||||
|
||||
// Regex to match URI. It respects the RFC 3986.
|
||||
// But many features are not supported like IP format.
|
||||
|
|
@ -92,7 +92,7 @@ var URI = (SUPPORTS_URL
|
|||
|
||||
var URI_REGEX = new RegExp(URI, 'g')
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
/* TODO: Supports:
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
backgroundColor: StartingCallStyle.avatar.backgroundColor
|
||||
image: _contact.avatar
|
||||
image: _contact.vcard.avatar
|
||||
username: contactDescription.username
|
||||
|
||||
height: _computeAvatarSize()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Utils 1.0
|
|||
|
||||
import App.Styles 1.0
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
ColumnLayout {
|
||||
function _removeContact (contact) {
|
||||
|
|
@ -24,9 +24,9 @@ ColumnLayout {
|
|||
|
||||
spacing: 0
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// Search Bar & actions.
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -66,9 +66,9 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// Contacts list.
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -89,7 +89,7 @@ ColumnLayout {
|
|||
height: ContactsStyle.contact.height
|
||||
width: parent.width
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
Rectangle {
|
||||
id: contact
|
||||
|
|
@ -97,7 +97,7 @@ ColumnLayout {
|
|||
anchors.fill: parent
|
||||
color: ContactsStyle.contact.backgroundColor.normal
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
Component {
|
||||
id: container1
|
||||
|
|
@ -142,7 +142,7 @@ ColumnLayout {
|
|||
ActionButton {
|
||||
icon: 'chat'
|
||||
onClicked: window.setView('Conversation', {
|
||||
sipAddress: $contact.sipAddress
|
||||
sipAddress: $contact.vcard.sipAddresses[0] // FIXME: Display menu if many addresses.
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -160,7 +160,7 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
Rectangle {
|
||||
id: indicator
|
||||
|
|
@ -185,15 +185,13 @@ ColumnLayout {
|
|||
}
|
||||
spacing: ContactsStyle.contact.spacing
|
||||
|
||||
// Avatar.
|
||||
Avatar {
|
||||
Layout.preferredHeight: ContactsStyle.contact.avatarSize
|
||||
Layout.preferredWidth: ContactsStyle.contact.avatarSize
|
||||
image: $contact.avatar
|
||||
username: $contact.username
|
||||
image: $contact.vcard.avatar
|
||||
username: $contact.vcard.username
|
||||
}
|
||||
|
||||
// Username.
|
||||
Text {
|
||||
Layout.preferredWidth: ContactsStyle.contact.username.width
|
||||
color: ContactsStyle.contact.username.color
|
||||
|
|
@ -204,7 +202,7 @@ ColumnLayout {
|
|||
pointSize: ContactsStyle.contact.username.fontSize
|
||||
}
|
||||
|
||||
text: $contact.username
|
||||
text: $contact.vcard.username
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
|
@ -214,7 +212,7 @@ ColumnLayout {
|
|||
hoverEnabled: true
|
||||
|
||||
onClicked: window.setView('ContactEdit', {
|
||||
sipAddress: $contact.sipAddress
|
||||
sipAddress: $contact.vcard.sipAddresses[0] // FIXME: Display menu if many addresses.
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -230,7 +228,7 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
states: State {
|
||||
when: mouseArea.containsMouse
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import QtQuick.Layouts 1.3
|
|||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import Utils 1.0
|
|||
|
||||
import App.Styles 1.0
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
|
|
@ -17,9 +17,9 @@ ApplicationWindow {
|
|||
contentLoader.setSource(view + '.qml', props || {})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// Window properties.
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
maximumHeight: MainWindowStyle.toolBar.height
|
||||
minimumHeight: MainWindowStyle.toolBar.height
|
||||
|
|
@ -30,9 +30,9 @@ ApplicationWindow {
|
|||
onActiveFocusItemChanged: activeFocusItem == null &&
|
||||
smartSearchBar.hideMenu()
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// Toolbar properties.
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
header: ToolBar {
|
||||
background: MainWindowStyle.toolBar.background
|
||||
|
|
@ -94,9 +94,9 @@ ApplicationWindow {
|
|||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// Content.
|
||||
// -----------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue