Commit 5166028a authored by camilo higuita's avatar camilo higuita
Browse files

overhaul of the contactpage and model backend

parent cbddcfc2
......@@ -50,7 +50,7 @@ set(communicator_HDRS
set(communicator_ASSETS
src/qml.qrc
assets/contacts_assets.qrc
assets/communicator_assets.qrc
)
add_executable(${PROJECT_NAME}
......@@ -74,7 +74,7 @@ add_subdirectory(src/communicator/linux)
else()
find_package(KF5 ${KF5_VERSION} REQUIRED COMPONENTS I18n Notifications Config KIO Attica Contacts People SyntaxHighlighting)
target_link_libraries(${PROJECT_NAME} KF5::ConfigCore KF5::Notifications KF5::KIOCore KF5::I18n KF5::Attica KF5::Contacts KF5::People KF5::SyntaxHighlighting)
target_link_libraries(${PROJECT_NAME} KF5::ConfigCore KF5::Notifications KF5::KIOCore KF5::I18n KF5::Attica KF5::Contacts KF5::People)
endif()
if (TARGET create-apk-communicator)
......@@ -84,10 +84,10 @@ endif()
target_link_libraries(${PROJECT_NAME} MauiKit Qt5::Sql Qt5::Qml Qt5::Widgets Qt5::Svg Qt5::Concurrent Qt5::Quick)
install(TARGETS ${PROJECT_NAME} ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES org.kde.communicator.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
install(FILES org.maui.communicator.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
#TODO: port to ecm_install_icons()
install(FILES assets/contacts.svg DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps)
install(FILES assets/communicator.svg DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/scalable/apps)
install(FILES org.maui.communicator.json DESTINATION /usr/share/maui-accounts/manifests)
#install(FILES org.kde.pix.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
......
<RCC>
<qresource prefix="/">
<file>portrait.jpg</file>
<file>contacts96.png</file>
<file>contacts72.png</file>
<file>contacts48.png</file>
<file>contacts.svg</file>
<file>view-contacts.svg</file>
<file>list-add-user.svg</file>
<file>amarok_artist.svg</file>
<file>star.svg</file>
<file>communicator.svg</file>
<file>communicator48.png</file>
<file>communicator64.png</file>
<file>communicator96.png</file>
</qresource>
</RCC>
logo.png

6.73 KB | W: | H:

logo.png

1.46 KB | W: | H:

logo.png
logo.png
logo.png
logo.png
  • 2-up
  • Swipe
  • Onion skin
[Desktop Entry]
Name=Contacts
Name[ca]=Contactes
Name[ca@valencia]=Contactes
Name[cs]=Kontakty
Name[es]=Contactos
Name[et]=Kontaktid
Name[fi]=Yhteystiedot
Name[fr]=Contacts
Name[it]=Contatti
Name[ko]=연락처
Name[lt]=Adresatai
Name[nl]=Contactpersonen
Name[nn]=Kontaktar
Name[pt]=Contactos
Name[pt_BR]=Contatos
Name[sl]=Stiki
Name[sv]=Kontakter
Name[uk]=Контакти
Name[x-test]=xxContactsxx
Name[zh_TW]=聯絡人
TryExec=contacts
Exec=contacts %U
Name=Communicator
TryExec=communicator
Exec=communicator %U
Terminal=false
Type=Application
Categories=Qt;KDE;System;
GenericName=Contacts
GenericName[ca]=Contactes
GenericName[ca@valencia]=Contactes
GenericName[cs]=Kontakty
GenericName[es]=Contactos
GenericName[et]=Kontaktid
GenericName[fi]=Yhteystiedot
GenericName[fr]=Contacts
GenericName[it]=Contatti
GenericName[ko]=연락처
GenericName[lt]=Adresatai
GenericName[nl]=Contactpersonen
GenericName[nn]=Kontaktar
GenericName[pt]=Contactos
GenericName[pt_BR]=Contatos
GenericName[sk]=Kontakty
GenericName[sl]=maui-communicator._desktop_
GenericName[sv]=Kontakter
GenericName[uk]=Контакти
GenericName[x-test]=xxContactsxx
GenericName[zh_TW]=聯絡人
GenericName=Contacts Manager
StartupNotify=true
Icon=maui-contacts
Icon=maui-communicator
MimeType=application/x-communicator;
......@@ -62,9 +62,9 @@ int main(int argc, char *argv[])
#endif
app.setOrganizationName(QStringLiteral("Maui"));
app.setWindowIcon(QIcon(":/contacts.png"));
app.setWindowIcon(QIcon("://communicator.svg"));
MauiApp::instance()->setHandleAccounts(false); //for now index can not handle cloud accounts
MauiApp::instance()->setIconName("qrc:/contacts.svg");
MauiApp::instance()->setIconName("qrc:/communicator.svg");
KLocalizedString::setApplicationDomain("communicator");
KAboutData about(QStringLiteral("communicator"), i18n("Communicator"), COMMUNICATOR_VERSION_STRING, i18n("Communicator keeps your contacts synced and organized across devices."),
......
......@@ -13,7 +13,7 @@ import "widgets"
Maui.ApplicationWindow
{
id: root
// title: Maui.App.displayName
altHeader: Kirigami.Settings.isMobile
readonly property var views : ({
favs: 0,
......@@ -23,6 +23,8 @@ Maui.ApplicationWindow
readonly property alias dialog: _dialogLoader.item
// autoHideHeader: swipeView.currentItem.currentItem ? swipeView.currentItem.currentItem.editing : false
Maui.AppViews
{
id: swipeView
......
......@@ -24,15 +24,11 @@ ContactsModel::ContactsModel(QObject *parent) : MauiList(parent), syncer(new Lin
qDebug() << "CONATCTS READY AT MODEL 1" << contacts;
emit this->preListChanged();
this->list = contacts;
this->listbk = this->list;
qDebug() << "CONATCTS READY AT MODEL" << this->list;
this->filter();
this->sortList();
emit this->postListChanged();
});
this->getList(true);
this->getList();
}
FMH::MODEL_LIST ContactsModel::items() const
......@@ -42,119 +38,29 @@ FMH::MODEL_LIST ContactsModel::items() const
void ContactsModel::setQuery(const QString &query)
{
if(this->query == query)
if(this->m_query == query || query.isEmpty())
return;
this->query = query;
this->m_query = query;
emit this->preListChanged();
this->filter();
emit this->postListChanged();
emit this->queryChanged();
}
QString ContactsModel::getQuery() const
{
return this->query;
}
void ContactsModel::setSortBy(const SORTBY &sort)
{
if(this->sort == sort)
return;
this->sort = sort;
this->preListChanged();
this->sortList();
this->postListChanged();
emit this->sortByChanged();
}
ContactsModel::SORTBY ContactsModel::getSortBy() const
{
return this->sort;
return this->m_query;
}
void ContactsModel::sortList()
{
if(this->sort == ContactsModel::SORTBY::NONE)
return;
const auto key = static_cast<FMH::MODEL_KEY>(this->sort);
std::sort(this->list.begin(), this->list.end(), [&key](const FMH::MODEL &e1, const FMH::MODEL &e2) -> bool
{
switch(key)
{
case FMH::MODEL_KEY::FAV:
{
if(e1[key].toInt() > e2[key].toInt())
return true;
break;
}
case FMH::MODEL_KEY::ADDDATE:
case FMH::MODEL_KEY::MODIFIED:
{
auto currentTime = QDateTime::currentDateTime();
auto date1 = QDateTime::fromString(e1[key], Qt::TextDate);
auto date2 = QDateTime::fromString(e2[key], Qt::TextDate);
if(date1.secsTo(currentTime) < date2.secsTo(currentTime))
return true;
break;
}
case FMH::MODEL_KEY::TITLE:
case FMH::MODEL_KEY::N:
case FMH::MODEL_KEY::TEL:
case FMH::MODEL_KEY::ORG:
case FMH::MODEL_KEY::EMAIL:
case FMH::MODEL_KEY::GENDER:
case FMH::MODEL_KEY::ADR:
{
const auto str1 = QString(e1[key]).toLower();
const auto str2 = QString(e2[key]).toLower();
if(str1 < str2)
return true;
break;
}
default:
if(e1[key] < e2[key])
return true;
}
return false;
});
}
void ContactsModel::getList(const bool &cached)
void ContactsModel::getList()
{
qDebug()<< "TRYING TO SET FULL LIST";
this->syncer->getContacts();
}
QVariantMap ContactsModel::get(const int &index) const
{
if(index >= this->list.size() || index < 0)
return QVariantMap();
QVariantMap res;
const auto index_ = this->mappedIndex(index);
const auto item = this->list.at(index_);
res = FMH::toMap(item);
#ifdef Q_OS_ANDROID
const auto id = this->list.at(index_)[FMH::MODEL_KEY::ID];
res.unite(FMH::toMap(this->syncer->getContact(id)));
#endif
return res;
}
bool ContactsModel::insert(const QVariantMap &map)
{
qDebug() << "INSERTING NEW CONTACT" << map;
......@@ -170,7 +76,6 @@ bool ContactsModel::insert(const QVariantMap &map)
emit this->preItemAppended();
this->list << model;
emit this->postItemAppended();
this->sortList();
qDebug()<< "inserting new contact count" << this->list.count();
......@@ -230,42 +135,23 @@ bool ContactsModel::remove(const int &index)
void ContactsModel::filter()
{
if(this->listbk.isEmpty())
return;
FMH::MODEL_LIST res;
if(this->query.isEmpty())
res = this->listbk;
else
{
if(this->query.contains("="))
if(this->m_query.contains("="))
{
auto q = this->query.split("=", QString::SkipEmptyParts);
auto q = this->m_query.split("=", QString::SkipEmptyParts);
if(q.size() == 2)
{
for(auto item : this->listbk)
for(auto item : this->list)
{
if(item[FMH::MODEL_NAME_KEY[q.first().trimmed()]].replace(" ", "").contains(q.last().trimmed()))
res << item;
}
}
}else
{
for(const auto &item : this->listbk)
{
for(auto data : item)
{
if((data.replace(" ", "").contains(this->query, Qt::CaseInsensitive)) && !res.contains(item))
res << item;
}
}
}
}
emit this->preListChanged();
this->list = res;
this->sortList();
emit this->postListChanged();
}
}
void ContactsModel::append(const QVariantMap &item)
......@@ -304,18 +190,6 @@ void ContactsModel::append(const QVariantMap &item, const int &at)
emit this->postItemAppended();
}
void ContactsModel::appendQuery(const QString &query)
{
if(query.isEmpty() || query == this->query)
return;
this->query = query;
emit this->preListChanged();
emit this->postListChanged();
}
void ContactsModel::clear()
{
emit this->preListChanged();
......@@ -325,13 +199,13 @@ void ContactsModel::clear()
void ContactsModel::reset()
{
this->query.clear();
this->getList(true);
this->m_query.clear();
this->getList();
}
void ContactsModel::refresh()
{
this->getList(false);
this->getList();
}
QVariantList ContactsModel::getAccounts()
......
......@@ -14,28 +14,8 @@ class ContactsModel : public MauiList
{
Q_OBJECT
Q_PROPERTY(QString query READ getQuery WRITE setQuery NOTIFY queryChanged)
Q_PROPERTY(ContactsModel::SORTBY sortBy READ getSortBy WRITE setSortBy NOTIFY sortByChanged)
public:
enum SORTBY : uint_fast8_t
{
ADDDATE = FMH::MODEL_KEY::ADDDATE, //when the contact was added
MODIFIED = FMH::MODEL_KEY::MODIFIED, // last modifed
N = FMH::MODEL_KEY::N, //contact name
TEL = FMH::MODEL_KEY::TEL, //contact phone
ORG = FMH::MODEL_KEY::ORG, //contact organization
EMAIl = FMH::MODEL_KEY::EMAIL, //contact email address
GENDER = FMH::MODEL_KEY::GENDER, //contact gender
ADR = FMH::MODEL_KEY::ADR, //contact phisical address
TITLE = FMH::MODEL_KEY::TITLE, //contact title
FAV = FMH::MODEL_KEY::FAV, //if contact if marked as fav
COUNT = FMH::MODEL_KEY::COUNT, //how many times contacts has been messaged or called
PHOTO = FMH::MODEL_KEY::PHOTO, //contact photo
NONE
}; Q_ENUM(SORTBY)
explicit ContactsModel(QObject *parent = nullptr);
FMH::MODEL_LIST items() const override final;
......@@ -43,9 +23,6 @@ public:
QString getQuery() const;
void setQuery(const QString &query);
void setSortBy(const ContactsModel::SORTBY &sort);
ContactsModel::SORTBY getSortBy() const;
private:
/*
* *syncer (abstract interface) shouyld work with whatever interface derived from
......@@ -61,26 +38,21 @@ private:
* when filtering the list
*/
FMH::MODEL_LIST list;
FMH::MODEL_LIST listbk;
void sortList();
void getList(const bool &cached = false);
void filter();
void getList();
/**
* query is a property to start filtering the list, the filtering is
* done over the list-bk cached list instead of the main list
*/
QString query = "undefined";
ContactsModel::SORTBY sort = ContactsModel::SORTBY::N;
QString m_query;
signals:
void queryChanged();
void sortByChanged();
public slots:
QVariantMap get(const int &index) const;
bool insert(const QVariantMap &map);
bool update(const QVariantMap &map, const int &index);
bool remove(const int &index);
......@@ -88,7 +60,6 @@ public slots:
void append(const QVariantMap &item, const int &at);
void append(const QVariantMap &item);
void appendQuery(const QString &query);
void clear();
void reset();
void refresh();
......
......@@ -11,5 +11,6 @@
<file>views/logs/LogsView.qml</file>
<file>views/dialer/DialerButton.qml</file>
<file>views/contacts/ContactsBrowser.qml</file>
<file>views/contacts/ContactField.qml</file>
</qresource>
</RCC>
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import org.kde.mauikit 1.2 as Maui
import org.kde.kirigami 2.9 as Kirigami
......@@ -12,15 +11,11 @@ Maui.SwipeBrowserDelegate
hoverEnabled: true
clip: true
Kirigami.Theme.colorSet: Kirigami.Theme.Button
// Kirigami.Theme.inherit: false
draggable: true
// property alias showMenuIcon: showQuickActions
signal favClicked(int index)
property int radius : Maui.Style.radiusV
iconSizeHint: Maui.Style.iconSizes.huge
label1.text: model.n
label1.font.pointSize: Maui.Style.fontSizes.big
......@@ -45,132 +40,7 @@ Maui.SwipeBrowserDelegate
label4.font.weight: Font.Light
label4.wrapMode: Text.WrapAnywhere
label4.elide: Text.ElideMiddle
iconVisible: control.width > Kirigami.Units.gridUnit * 15
template.iconComponent: Item
{
id: _contactPic
Rectangle
{
Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
Kirigami.Theme.inherit: false
height: parent.height * 0.8
width: height
anchors.centerIn: parent
radius: control.radius
color: Kirigami.Theme.backgroundColor
border.color: Qt.darker(color, 1.5)
Loader
{
id: _contactPicLoader
anchors.fill: parent
sourceComponent: model.photo ? _imgComponent : _iconComponent
}
Component
{
id: _imgComponent
Image
{
id: _img
width: parent.width
height: width
anchors.centerIn: parent
sourceSize.width: parent.width
sourceSize.height: parent.height
fillMode: Image.PreserveAspectCrop
cache: true
antialiasing: true
smooth: true
asynchronous: true
source: "image://contact/"+ model.id
layer.enabled: true
layer.effect: OpacityMask
{
maskSource: Item
{
width: _img.width
height: _img.height
Rectangle
{
anchors.centerIn: parent
width: _img.width
height: _img.height
radius: control.radius
}
}
}
}
}
Component
{
id: _iconComponent
Label
{
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
color: Kirigami.Theme.textColor
font.pointSize: Maui.Style.fontSizes.huge
font.bold: true
font.weight: Font.Bold
text: model.n[0].toUpperCase()
}
}
}
}
quickActions: [
// Action
// {
// icon.name: "draw-star"
// onTriggered:
// {
// control.favClicked(index)
// }
// icon.color: model.fav == "1" ? "yellow" : Kirigami.Theme.textColor
// },
Action
{
icon.name: "message-new"
icon.color: Kirigami.Theme.textColor
onTriggered:
{
_dialogLoader.sourceComponent = _messageComposerComponent
dialog.contact = list.get(index)
dialog.open()
}
},
Action
{
enabled: Kirigami.Settings.isMobile
icon.name: "call-start"
icon.color: Kirigami.Theme.textColor
onTriggered:
{
if(Maui.Handy.isAndroid)
Maui.Android.call(model.tel)
else
Qt.openUrlExternally("call://" + model.tel)
iconVisible: control.width > Kirigami.Units.gridUnit * 15
}
}