From 7efc755bcc4f8863867ee7ee6f803e774a264324 Mon Sep 17 00:00:00 2001 From: "Andrew E. Bruno" Date: Sat, 4 Mar 2017 21:23:05 -0500 Subject: [PATCH] Refactor contact model --- model/contact.go | 112 +++++++++++++++++++++++++++++---------- qml/pages/NewMessage.qml | 2 +- store/contact.go | 100 ++-------------------------------- ui/gui.go | 4 +- worker/setup.go | 13 ++++- 5 files changed, 101 insertions(+), 130 deletions(-) diff --git a/model/contact.go b/model/contact.go index 8d673304b..e08db5994 100644 --- a/model/contact.go +++ b/model/contact.go @@ -25,19 +25,21 @@ import ( "github.com/aebruno/whisperfish/settings" "github.com/aebruno/whisperfish/store" "github.com/therecipe/qt/core" + "github.com/ttacon/libphonenumber" ) //go:generate qtmoc -type Contact struct { +type ContactModel struct { core.QObject - settings *settings.Settings - contactStore *store.Contact + contacts []*store.Contact + registeredContacts []textsecure.Contact + settings *settings.Settings _ func() `constructor:"init"` _ func() `signal:"refreshComplete"` _ func(tel string) string `slot:"format"` - _ func(tel string) bool `slot:"exists"` + _ func(tel string) bool `slot:"registered"` _ func(tel string) string `slot:"identity"` _ func(tel string) string `slot:"name"` _ func() int `slot:"total"` @@ -45,38 +47,90 @@ type Contact struct { } // Setup connections -func (c *Contact) init() { - c.settings = settings.NewSettings(nil) - c.contactStore = store.NewContact() +func (model *ContactModel) init() { + model.settings = settings.NewSettings(nil) + model.contacts = make([]*store.Contact, 0) + model.registeredContacts = make([]textsecure.Contact, 0) // Slot connections - c.ConnectIdentity(func(source string) string { - return c.identity(source) - }) - c.ConnectFormat(func(tel string) string { - return c.contactStore.Format(tel, c.settings.GetString("country_code")) - }) - c.ConnectExists(func(tel string) bool { - return c.contactStore.Exists(tel, c.settings.GetString("country_code")) - }) - c.ConnectName(func(tel string) string { - return c.contactStore.FindName(tel) - }) - c.ConnectTotal(func() int { - if !c.settings.GetBool("share_contacts") { - return 0 + model.ConnectIdentity(model.identity) + model.ConnectFormat(model.format) + model.ConnectRegistered(model.registered) + model.ConnectName(model.name) + model.ConnectTotal(model.total) + model.ConnectRefresh(model.refresh) +} + +// Format contact number +func (model *ContactModel) format(tel string) string { + num, err := libphonenumber.Parse(tel, model.settings.GetString("country_code")) + if err != nil { + return "" + } + + n := libphonenumber.Format(num, libphonenumber.E164) + return n +} + +// Returns the name of the contact +func (model *ContactModel) name(tel string) string { + for _, r := range model.contacts { + if r.Tel == tel { + return r.Name } + } + + // name not found. just return number + return tel +} + +// Returns the total number of contacts registered with signal +func (model *ContactModel) total() int { + return len(model.registeredContacts) +} + +// Refresh contacts +func (model *ContactModel) refresh() { + var err error + model.contacts, err = store.SailfishContacts(model.settings.GetString("country_code")) + if err != nil { + log.WithFields(log.Fields{ + "error": err, + }).Error("Failed to fetch local contacts") + model.contacts = make([]*store.Contact, 0) + } + + if model.settings.GetBool("share_contacts") { + model.registeredContacts, err = textsecure.GetRegisteredContacts() + if err != nil { + log.WithFields(log.Fields{ + "error": err, + }).Error("Failed to fetch signal contacts") + model.registeredContacts = make([]textsecure.Contact, 0) + } + } +} + +// Check if contact is registered with signal +func (model *ContactModel) registered(tel string) bool { + num, err := libphonenumber.Parse(tel, model.settings.GetString("country_code")) + if err != nil { + return false + } + + n := libphonenumber.Format(num, libphonenumber.E164) + + for _, r := range model.registeredContacts { + if r.Tel == n { + return true + } + } - return c.contactStore.RegisteredContacts() - }) - c.ConnectRefresh(func() { - c.contactStore.Refresh(c.settings.GetString("country_code")) - c.RefreshComplete() - }) + return false } // Returns identity of contact -func (c *Contact) identity(source string) string { +func (model *ContactModel) identity(source string) string { id, err := textsecure.ContactIdentityKey(source) if err != nil { log.WithFields(log.Fields{ diff --git a/qml/pages/NewMessage.qml b/qml/pages/NewMessage.qml index 40c86cfa5..92596ef0b 100644 --- a/qml/pages/NewMessage.qml +++ b/qml/pages/NewMessage.qml @@ -86,7 +86,7 @@ Page { var contact = selectedContacts.get(i) if (contact.property !== undefined && contact.propertyType === "phoneNumber") { var tel = ContactModel.format(contact.property.number) - exists = ContactModel.exists(contact.property.number) + exists = ContactModel.registered(contact.property.number) if(tel.length != 0){ recipients[tel] = true } else { diff --git a/store/contact.go b/store/contact.go index 1bdef5c43..a81506f18 100644 --- a/store/contact.go +++ b/store/contact.go @@ -19,7 +19,6 @@ package store import ( log "github.com/Sirupsen/logrus" - "github.com/aebruno/textsecure" "github.com/jmoiron/sqlx" _ "github.com/mutecomm/go-sqlcipher" "github.com/ttacon/libphonenumber" @@ -31,103 +30,12 @@ const ( ) type Contact struct { - contacts []textsecure.Contact -} - -func NewContact() *Contact { - c := &Contact{} - return c -} - -func (c *Contact) Len() int { - return len(c.contacts) -} - -func (c *Contact) RegisteredContacts() int { - contacts, err := textsecure.GetRegisteredContacts() - if err != nil { - log.WithFields(log.Fields{ - "error": err, - }).Error("Failed to fetch signal contacts") - return 0 - } - - count := 0 - for _, l := range c.contacts { - for _, r := range contacts { - if l.Tel == r.Tel { - count++ - break - } - } - } - - return count -} - -func (c *Contact) Refresh(country string) { - contacts, err := SailfishContacts(country) - if err != nil { - log.WithFields(log.Fields{ - "error": err, - }).Error("Failed to refresh contacts") - c.contacts = make([]textsecure.Contact, 0) - } - - c.contacts = contacts -} - -// Get name of contact with number tel -func (c *Contact) FindName(tel string) string { - for _, r := range c.contacts { - if r.Tel == tel { - return r.Name - } - } - - // name not found. just return number - return tel -} - -// Format contact tel -func (c *Contact) Format(tel, countryCode string) string { - num, err := libphonenumber.Parse(tel, countryCode) - if err != nil { - return "" - } - - n := libphonenumber.Format(num, libphonenumber.E164) - return n -} - -// Check if contact is registered with Signal -func (c *Contact) Exists(tel, countryCode string) bool { - num, err := libphonenumber.Parse(tel, countryCode) - if err != nil { - return false - } - - n := libphonenumber.Format(num, libphonenumber.E164) - - contacts, err := textsecure.GetRegisteredContacts() - if err != nil { - log.WithFields(log.Fields{ - "error": err, - }).Error("Failed to fetch signal contacts") - return false - } - - for _, r := range contacts { - if r.Tel == n { - return true - } - } - - return false + Name string `db:"name"` + Tel string `db:"tel"` } // Get local sailfish contacts -func SailfishContacts(country string) ([]textsecure.Contact, error) { +func SailfishContacts(country string) ([]*Contact, error) { db, err := sqlx.Open("sqlite3", QtcontactsPath) if err != nil { log.WithFields(log.Fields{ @@ -136,7 +44,7 @@ func SailfishContacts(country string) ([]textsecure.Contact, error) { return nil, err } - contacts := []textsecure.Contact{} + contacts := []*Contact{} err = db.Select(&contacts, ` select c.displayLabel as name, diff --git a/ui/gui.go b/ui/gui.go index 6c6e0559d..69139f4a1 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -130,7 +130,7 @@ func Run(version string) { } var filePicker = model.NewFilePicker(nil) - var contactModel = model.NewContact(nil) + var contactModel = model.NewContactModel(nil) var prompt = model.NewPrompt(nil) var sessionModel = model.NewSessionModel(nil) var messageModel = model.NewMessageModel(nil) @@ -224,11 +224,11 @@ func Run(version string) { return } - setupWorker.SetLocked(false) contactModel.Refresh() sessionModel.Reload() deviceModel.Reload() clientWorker.StartConnection() + setupWorker.SetLocked(false) }) messageModel.ConnectSendMessage(func(mid int64) { diff --git a/worker/setup.go b/worker/setup.go index fd882319e..9538619bf 100644 --- a/worker/setup.go +++ b/worker/setup.go @@ -124,11 +124,20 @@ func (s *SetupWorker) Run(client *textsecure.Client) { } client.GetLocalContacts = func() ([]textsecure.Contact, error) { log.Debug("Get local contacts handler") + contacts := make([]textsecure.Contact, 0) + if s.settings.GetBool("share_contacts") { - return store.SailfishContacts(s.settings.GetString("country_code")) + local, err := store.SailfishContacts(s.settings.GetString("country_code")) + if err != nil { + return contacts, nil + } + + for _, c := range local { + contacts = append(contacts, textsecure.Contact{Name: c.Name, Tel: c.Tel}) + } } - return make([]textsecure.Contact, 0), nil + return contacts, nil } err := textsecure.Setup(client)