Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Commit

Permalink
Refactor contact model
Browse files Browse the repository at this point in the history
  • Loading branch information
aebruno committed Mar 5, 2017
1 parent c0bf38d commit 7efc755
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 130 deletions.
112 changes: 83 additions & 29 deletions model/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,58 +25,112 @@ 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"`
_ func() `slot:"refresh"`
}

// 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{
Expand Down
2 changes: 1 addition & 1 deletion qml/pages/NewMessage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
100 changes: 4 additions & 96 deletions store/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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{
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions ui/gui.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down
13 changes: 11 additions & 2 deletions worker/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 7efc755

Please sign in to comment.