remove photo path in favor of images in contact
This commit is contained in:
parent
1adfa38611
commit
31a885ced8
|
@ -157,20 +157,13 @@ func (db *Database) GetIdentityImages(keyUID string) ([]*images.IdentityImage, e
|
|||
}
|
||||
|
||||
func (db *Database) GetIdentityImage(keyUID, it string) (*images.IdentityImage, error) {
|
||||
rows, err := db.db.Query("SELECT key_uid, name, image_payload, width, height, file_size, resize_target FROM identity_images WHERE key_uid = ? AND name = ?", keyUID, it)
|
||||
if err != nil {
|
||||
var ii images.IdentityImage
|
||||
err := db.db.QueryRow("SELECT key_uid, name, image_payload, width, height, file_size, resize_target FROM identity_images WHERE key_uid = ? AND name = ?", keyUID, it).Scan(&ii.KeyUID, &ii.Name, &ii.Payload, &ii.Width, &ii.Height, &ii.FileSize, &ii.ResizeTarget)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var ii images.IdentityImage
|
||||
for rows.Next() {
|
||||
err = rows.Scan(&ii.KeyUID, &ii.Name, &ii.Payload, &ii.Width, &ii.Height, &ii.FileSize, &ii.ResizeTarget)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &ii, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/images"
|
||||
"github.com/status-im/status-go/protocol/identity/alias"
|
||||
"github.com/status-im/status-go/protocol/identity/identicon"
|
||||
)
|
||||
|
@ -28,7 +29,6 @@ type ContactDeviceInfo struct {
|
|||
|
||||
// Contact has information about a "Contact". A contact is not necessarily one
|
||||
// that we added or added us, that's based on SystemTags.
|
||||
// TODO remove use of photoPath in Contact{}
|
||||
type Contact struct {
|
||||
// ID of the contact. It's a hex-encoded public key (prefixed with 0x).
|
||||
ID string `json:"id"`
|
||||
|
@ -49,8 +49,6 @@ type Contact struct {
|
|||
Alias string `json:"alias,omitempty"`
|
||||
// Identicon generated from public key
|
||||
Identicon string `json:"identicon"`
|
||||
// Photo is the base64 encoded photo
|
||||
Photo string `json:"photoPath,omitempty"`
|
||||
// LastUpdated is the last time we received an update from the contact
|
||||
// updates should be discarded if last updated is less than the one stored
|
||||
LastUpdated uint64 `json:"lastUpdated"`
|
||||
|
@ -61,6 +59,8 @@ type Contact struct {
|
|||
DeviceInfo []ContactDeviceInfo `json:"deviceInfo"`
|
||||
TributeToTalk string `json:"tributeToTalk,omitempty"`
|
||||
LocalNickname string `json:"localNickname,omitempty"`
|
||||
|
||||
Images map[string]images.IdentityImage `json:"images"`
|
||||
}
|
||||
|
||||
func (c Contact) PublicKey() (*ecdsa.PublicKey, error) {
|
||||
|
|
|
@ -237,7 +237,6 @@ func (m *MessageHandler) HandleSyncInstallationContact(state *ReceivedMessageSta
|
|||
contact.Name = message.EnsName
|
||||
contact.ENSVerified = false
|
||||
}
|
||||
contact.Photo = message.ProfileImage
|
||||
contact.LastUpdated = message.Clock
|
||||
contact.LocalNickname = message.LocalNickname
|
||||
|
||||
|
@ -286,7 +285,6 @@ func (m *MessageHandler) HandleContactUpdate(state *ReceivedMessageState, messag
|
|||
contact.Name = message.EnsName
|
||||
contact.ENSVerified = false
|
||||
}
|
||||
contact.Photo = message.ProfileImage
|
||||
contact.LastUpdated = message.Clock
|
||||
state.ModifiedContacts[contact.ID] = true
|
||||
state.AllContacts[contact.ID] = contact
|
||||
|
@ -807,72 +805,23 @@ func (m *MessageHandler) HandleGroupChatInvitation(state *ReceivedMessageState,
|
|||
func (m *MessageHandler) HandleChatIdentity(state *ReceivedMessageState, ci protobuf.ChatIdentity) error {
|
||||
logger := m.logger.With(zap.String("site", "HandleChatIdentity"))
|
||||
contact := state.CurrentMessageState.Contact
|
||||
chat, ok := state.AllChats[contact.ID]
|
||||
if !ok {
|
||||
chat = OneToOneFromPublicKey(state.CurrentMessageState.PublicKey, state.Timesource)
|
||||
// We don't want to show the chat to the user
|
||||
chat.Active = false
|
||||
}
|
||||
|
||||
logger.Info("Handling contact update")
|
||||
newImages, err := m.persistence.SaveContactChatIdentity(contact.ID, &ci)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if newImages {
|
||||
for imageType, image := range ci.Images {
|
||||
if contact.Images == nil {
|
||||
contact.Images = make(map[string]images.IdentityImage)
|
||||
}
|
||||
contact.Images[imageType] = images.IdentityImage{Name: imageType, Payload: image.Payload}
|
||||
|
||||
// TODO investigate potential race condition where user updates this contact's details and the contact update's
|
||||
// clock value is just less than the ChatIdentity clock and the ChatIdentity is processed first.
|
||||
// In this case the contact update would not be processed
|
||||
//
|
||||
// TODO Potential fix: create an ChatIdentity last updated field on the contact table.
|
||||
logger.Info(fmt.Sprintf("Update times, contact.LastUpdated '%d', ChatIdentity.Clock '%d'", contact.LastUpdated, ci.Clock))
|
||||
if contact.LastUpdated < ci.Clock {
|
||||
logger.Info("Updating contact")
|
||||
if !contact.HasBeenAdded() && contact.ID != contactIDFromPublicKey(&m.identity.PublicKey) {
|
||||
contact.SystemTags = append(contact.SystemTags, contactRequestReceived)
|
||||
}
|
||||
|
||||
// TODO handle ENS things
|
||||
/* if contact.Name != message.EnsName {
|
||||
contact.Name = message.EnsName
|
||||
contact.ENSVerified = false
|
||||
} */
|
||||
|
||||
logger.Info(fmt.Sprintf("ChatIdentity has %d images attached", len(ci.Images)))
|
||||
if len(ci.Images) > 0 {
|
||||
// Get the largest
|
||||
var name string
|
||||
var iiSize int
|
||||
for n, ii := range ci.Images {
|
||||
if iiSize < len(ii.Payload) {
|
||||
iiSize = len(ii.Payload)
|
||||
name = n
|
||||
}
|
||||
}
|
||||
|
||||
logger.Info(fmt.Sprintf("largest image : name '%s', size '%d'", name, iiSize))
|
||||
|
||||
if ci.Images[name] == nil {
|
||||
logger.Info("image empty")
|
||||
return errors.New("image empty")
|
||||
}
|
||||
|
||||
dataURI, err := images.GetPayloadDataURI(ci.Images[name].Payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
contact.Photo = dataURI
|
||||
|
||||
logger.Info(fmt.Sprintf("image payload '%s'", dataURI))
|
||||
}
|
||||
|
||||
contact.LastUpdated = ci.Clock
|
||||
state.ModifiedContacts[contact.ID] = true
|
||||
state.AllContacts[contact.ID] = contact
|
||||
}
|
||||
|
||||
if chat.LastClockValue < ci.Clock {
|
||||
chat.LastClockValue = ci.Clock
|
||||
}
|
||||
|
||||
state.ModifiedChats[chat.ID] = true
|
||||
state.AllChats[chat.ID] = chat
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2413,7 +2413,6 @@ func (m *Messenger) syncContact(ctx context.Context, contact *Contact) error {
|
|||
Clock: clock,
|
||||
Id: contact.ID,
|
||||
EnsName: contact.Name,
|
||||
ProfileImage: contact.Photo,
|
||||
LocalNickname: contact.LocalNickname,
|
||||
}
|
||||
encodedMessage, err := proto.Marshal(syncMessage)
|
||||
|
|
|
@ -112,7 +112,6 @@ func (s *MessengerContactUpdateSuite) TestReceiveContactUpdate() {
|
|||
|
||||
receivedContact := response.Contacts[0]
|
||||
s.Require().Equal(theirName, receivedContact.Name)
|
||||
s.Require().Equal(theirPicture, receivedContact.Photo)
|
||||
s.Require().False(receivedContact.ENSVerified)
|
||||
s.Require().True(receivedContact.HasBeenAdded())
|
||||
s.Require().NotEmpty(receivedContact.LastUpdated)
|
||||
|
@ -135,7 +134,6 @@ func (s *MessengerContactUpdateSuite) TestReceiveContactUpdate() {
|
|||
receivedContact = response.Contacts[0]
|
||||
s.Require().Equal(theirContactID, receivedContact.ID)
|
||||
s.Require().Equal(newName, receivedContact.Name)
|
||||
s.Require().Equal(newPicture, receivedContact.Photo)
|
||||
s.Require().False(receivedContact.ENSVerified)
|
||||
s.Require().True(receivedContact.HasBeenAdded())
|
||||
s.Require().NotEmpty(receivedContact.LastUpdated)
|
||||
|
|
|
@ -631,7 +631,6 @@ func (s *MessengerSuite) TestRetrieveBlockedContact() {
|
|||
blockedContact := Contact{
|
||||
ID: publicKeyHex,
|
||||
Name: "contact-name",
|
||||
Photo: "contact-photo",
|
||||
LastUpdated: 20,
|
||||
SystemTags: []string{contactBlocked},
|
||||
TributeToTalk: "talk",
|
||||
|
@ -1192,7 +1191,6 @@ func (s *MessengerSuite) TestBlockContact() {
|
|||
contact := Contact{
|
||||
ID: testPK,
|
||||
Name: "contact-name",
|
||||
Photo: "contact-photo",
|
||||
LastUpdated: 20,
|
||||
SystemTags: []string{contactAdded, contactRequestReceived},
|
||||
DeviceInfo: []ContactDeviceInfo{
|
||||
|
@ -1375,7 +1373,6 @@ func (s *MessengerSuite) TestContactPersistence() {
|
|||
ID: testPK,
|
||||
|
||||
Name: "contact-name",
|
||||
Photo: "contact-photo",
|
||||
LastUpdated: 20,
|
||||
SystemTags: []string{contactAdded, contactRequestReceived},
|
||||
DeviceInfo: []ContactDeviceInfo{
|
||||
|
@ -1410,7 +1407,6 @@ func (s *MessengerSuite) TestContactPersistenceUpdate() {
|
|||
contact := Contact{
|
||||
ID: contactID,
|
||||
Name: "contact-name",
|
||||
Photo: "contact-photo",
|
||||
LastUpdated: 20,
|
||||
SystemTags: []string{contactAdded, contactRequestReceived},
|
||||
DeviceInfo: []ContactDeviceInfo{
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
// 1603816533_add_links.down.sql (0)
|
||||
// 1603816533_add_links.up.sql (48B)
|
||||
// 1603888149_create_chat_identity_last_published_table.down.sql (40B)
|
||||
// 1603888149_create_chat_identity_last_published_table.up.sql (175B)
|
||||
// 1603888149_create_chat_identity_last_published_table.up.sql (407B)
|
||||
// doc.go (850B)
|
||||
|
||||
package migrations
|
||||
|
@ -742,7 +742,7 @@ func _1603888149_create_chat_identity_last_published_tableDownSql() (*asset, err
|
|||
return a, nil
|
||||
}
|
||||
|
||||
var __1603888149_create_chat_identity_last_published_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x3c\xcb\x41\xaa\xc2\x30\x14\x85\xe1\x79\xa1\x7b\x38\xc3\xf7\xc0\x1d\x38\x4a\xc3\x2d\x06\x63\x52\xd2\xab\xd8\x51\x88\x6d\x21\xc5\xa0\x42\x53\xc1\xdd\x0b\x05\x3b\x3d\xe7\xff\xa4\x23\xc1\x04\x16\x95\x26\xa8\x1a\xc6\x32\xe8\xaa\x5a\x6e\xd1\xc7\x90\xfd\x34\x8c\x8f\x3c\xe5\x8f\x4f\x61\xce\xfe\xb5\xdc\xd2\x34\xc7\x71\xc0\x5f\x59\xe0\x57\xe0\x22\x9c\x3c\x08\xb7\x62\x73\xd6\x1a\x8d\x53\x27\xe1\x3a\x1c\xa9\x83\x35\x90\xd6\xd4\x5a\x49\x86\xa3\x46\x0b\x49\xbb\x15\xa7\x67\x7f\xf7\xef\x90\x96\x11\xca\xf0\x86\xd7\x33\x86\x39\xa2\xd2\xb6\xda\xe6\xb2\xf8\xdf\x97\xc5\x37\x00\x00\xff\xff\x0a\xfa\x7a\x2a\xaf\x00\x00\x00")
|
||||
var __1603888149_create_chat_identity_last_published_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x90\xc1\x4a\xc4\x30\x10\x86\xef\x85\xbe\xc3\x1c\x77\x61\xdf\xc0\x53\x1a\x66\x31\x18\xd3\x35\x9b\x8a\x7b\x0a\x63\x1b\x4c\x30\x6e\x0b\xc9\x0a\x7d\x7b\x21\xab\x55\xa1\x88\xc7\xe4\x9f\x9f\xef\x9b\xe1\x1a\x99\x41\x30\xac\x91\x08\x62\x0f\xaa\x35\x80\x4f\xe2\x68\x8e\xd0\x7b\xca\x36\x0c\xee\x9c\x43\x9e\x6d\xa4\x94\xed\x74\x79\x8e\x21\x79\x37\xc0\xa6\xae\xe0\x6b\x02\x1e\x99\xe6\xb7\x4c\x97\xb2\xea\xa4\x84\x83\x16\xf7\x4c\x9f\xe0\x0e\x4f\xd0\x2a\xe0\xad\xda\x4b\xc1\x0d\x68\x3c\x48\xc6\x71\x57\xca\x71\xec\x5f\xed\x3b\xc5\x8b\x03\xa1\xcc\x52\x2e\xa1\xa7\xe4\xa1\x91\x6d\xb3\x7c\xd7\xd5\xf6\xa6\xae\xea\xea\xdf\xc2\xfd\x78\xce\xd4\xe7\xf4\xa9\x7a\x7d\xad\xd9\x16\x60\x78\xa3\x17\x67\xf3\x3c\xb9\xf5\xfc\x4f\xdb\x89\xe6\x38\xd2\xf0\x5b\xb8\x24\x9d\x12\x0f\x1d\x6e\xbe\xe9\xbb\x1f\xa4\xed\xda\x6d\xae\x7b\x7e\x04\x00\x00\xff\xff\xff\xdb\x89\x48\x97\x01\x00\x00")
|
||||
|
||||
func _1603888149_create_chat_identity_last_published_tableUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
|
@ -757,8 +757,8 @@ func _1603888149_create_chat_identity_last_published_tableUpSql() (*asset, error
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1603888149_create_chat_identity_last_published_table.up.sql", size: 175, mode: os.FileMode(0644), modTime: time.Unix(1608048601, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb0, 0x9b, 0x9a, 0xb6, 0x33, 0x2e, 0xb1, 0x8b, 0xe4, 0x18, 0x90, 0xe, 0x40, 0xa4, 0xdd, 0x13, 0x3f, 0x50, 0x55, 0x7, 0x31, 0x50, 0xe0, 0xb8, 0x1e, 0x51, 0xcc, 0xfd, 0xa5, 0x7e, 0x3, 0x7b}}
|
||||
info := bindataFileInfo{name: "1603888149_create_chat_identity_last_published_table.up.sql", size: 407, mode: os.FileMode(0644), modTime: time.Unix(1608048655, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7f, 0x9, 0xf, 0xfb, 0xdb, 0x3c, 0x86, 0x70, 0x82, 0xda, 0x10, 0x25, 0xe2, 0x4e, 0x40, 0x45, 0xab, 0x8b, 0x1c, 0x91, 0x7c, 0xf1, 0x70, 0x2e, 0x81, 0xf3, 0x71, 0x45, 0xda, 0xe2, 0xa4, 0x57}}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -3,3 +3,11 @@ CREATE TABLE IF NOT EXISTS chat_identity_last_published (
|
|||
clock_value INT NOT NULL,
|
||||
hash BLOB NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS chat_identity_contacts (
|
||||
contact_id VARCHAR NOT NULL,
|
||||
image_type VARCHAR NOT NULL,
|
||||
clock_value INT NOT NULL,
|
||||
payload BLOB NOT NULL,
|
||||
UNIQUE(contact_id, image_type) ON CONFLICT REPLACE
|
||||
);
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
"github.com/status-im/status-go/images"
|
||||
"github.com/status-im/status-go/protocol/common"
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
)
|
||||
|
@ -378,44 +379,50 @@ func (db sqlitePersistence) Chat(chatID string) (*Chat, error) {
|
|||
}
|
||||
|
||||
func (db sqlitePersistence) Contacts() ([]*Contact, error) {
|
||||
allContacts := make(map[string]*Contact)
|
||||
|
||||
rows, err := db.db.Query(`
|
||||
SELECT
|
||||
id,
|
||||
address,
|
||||
name,
|
||||
alias,
|
||||
identicon,
|
||||
photo,
|
||||
last_updated,
|
||||
system_tags,
|
||||
device_info,
|
||||
ens_verified,
|
||||
ens_verified_at,
|
||||
tribute_to_talk,
|
||||
local_nickname
|
||||
FROM contacts
|
||||
c.id,
|
||||
c.address,
|
||||
c.name,
|
||||
c.alias,
|
||||
c.identicon,
|
||||
c.last_updated,
|
||||
c.system_tags,
|
||||
c.device_info,
|
||||
c.ens_verified,
|
||||
c.ens_verified_at,
|
||||
c.tribute_to_talk,
|
||||
c.local_nickname,
|
||||
i.image_type,
|
||||
i.payload
|
||||
FROM contacts c LEFT JOIN chat_identity_contacts i ON c.id = i.contact_id
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var response []*Contact
|
||||
|
||||
for rows.Next() {
|
||||
|
||||
var (
|
||||
contact Contact
|
||||
encodedDeviceInfo []byte
|
||||
encodedSystemTags []byte
|
||||
nickname sql.NullString
|
||||
imageType sql.NullString
|
||||
imagePayload []byte
|
||||
)
|
||||
|
||||
contact.Images = make(map[string]images.IdentityImage)
|
||||
|
||||
err := rows.Scan(
|
||||
&contact.ID,
|
||||
&contact.Address,
|
||||
&contact.Name,
|
||||
&contact.Alias,
|
||||
&contact.Identicon,
|
||||
&contact.Photo,
|
||||
&contact.LastUpdated,
|
||||
&encodedSystemTags,
|
||||
&encodedDeviceInfo,
|
||||
|
@ -423,6 +430,8 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
|
|||
&contact.ENSVerifiedAt,
|
||||
&contact.TributeToTalk,
|
||||
&nickname,
|
||||
&imageType,
|
||||
&imagePayload,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -448,12 +457,89 @@ func (db sqlitePersistence) Contacts() ([]*Contact, error) {
|
|||
}
|
||||
}
|
||||
|
||||
response = append(response, &contact)
|
||||
previousContact, ok := allContacts[contact.ID]
|
||||
if !ok {
|
||||
|
||||
if imageType.Valid {
|
||||
contact.Images[imageType.String] = images.IdentityImage{Name: imageType.String, Payload: imagePayload}
|
||||
}
|
||||
|
||||
allContacts[contact.ID] = &contact
|
||||
|
||||
} else if imageType.Valid {
|
||||
previousContact.Images[imageType.String] = images.IdentityImage{Name: imageType.String, Payload: imagePayload}
|
||||
allContacts[contact.ID] = previousContact
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var response []*Contact
|
||||
for key := range allContacts {
|
||||
response = append(response, allContacts[key])
|
||||
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) SaveContactChatIdentity(contactID string, chatIdentity *protobuf.ChatIdentity) (updated bool, err error) {
|
||||
if chatIdentity.Clock == 0 {
|
||||
return false, errors.New("clock value unset")
|
||||
}
|
||||
|
||||
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
err = tx.Commit()
|
||||
return
|
||||
}
|
||||
// don't shadow original error
|
||||
_ = tx.Rollback()
|
||||
}()
|
||||
|
||||
for imageType, image := range chatIdentity.Images {
|
||||
var exists bool
|
||||
err := tx.QueryRow(`SELECT EXISTS(SELECT 1 FROM chat_identity_contacts WHERE contact_id = ? AND image_type = ? AND clock_value >= ?)`, contactID, imageType, chatIdentity.Clock).Scan(&exists)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if exists {
|
||||
continue
|
||||
}
|
||||
|
||||
stmt, err := tx.Prepare(`INSERT INTO chat_identity_contacts (contact_id, image_type, clock_value, payload) VALUES (?, ?, ?, ?)`)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer stmt.Close()
|
||||
if image.Payload == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Validate image URI to make sure it's serializable
|
||||
_, err = images.GetPayloadDataURI(image.Payload)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
_, err = stmt.Exec(
|
||||
contactID,
|
||||
imageType,
|
||||
chatIdentity.Clock,
|
||||
image.Payload,
|
||||
)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
updated = true
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) SaveRawMessage(message *common.RawMessage) error {
|
||||
var pubKeys [][]byte
|
||||
for _, pk := range message.Recipients {
|
||||
|
@ -649,15 +735,15 @@ func (db sqlitePersistence) SaveContact(contact *Contact, tx *sql.Tx) (err error
|
|||
name,
|
||||
alias,
|
||||
identicon,
|
||||
photo,
|
||||
last_updated,
|
||||
system_tags,
|
||||
device_info,
|
||||
ens_verified,
|
||||
ens_verified_at,
|
||||
tribute_to_talk,
|
||||
local_nickname
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)
|
||||
local_nickname,
|
||||
photo
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?, ?)
|
||||
`)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -670,7 +756,6 @@ func (db sqlitePersistence) SaveContact(contact *Contact, tx *sql.Tx) (err error
|
|||
contact.Name,
|
||||
contact.Alias,
|
||||
contact.Identicon,
|
||||
contact.Photo,
|
||||
contact.LastUpdated,
|
||||
encodedSystemTags.Bytes(),
|
||||
encodedDeviceInfo.Bytes(),
|
||||
|
@ -678,6 +763,9 @@ func (db sqlitePersistence) SaveContact(contact *Contact, tx *sql.Tx) (err error
|
|||
contact.ENSVerifiedAt,
|
||||
contact.TributeToTalk,
|
||||
contact.LocalNickname,
|
||||
// Photo is not used anymore but constrained to be NOT NULL
|
||||
// we set it to blank for now to avoid a migration of the table
|
||||
"",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -671,6 +671,54 @@ func TestSqlitePersistence_GetWhenChatIdentityLastPublished(t *testing.T) {
|
|||
require.Nil(t, actualHash2)
|
||||
}
|
||||
|
||||
func TestSaveContactIdentityImage(t *testing.T) {
|
||||
db, err := openTestDB()
|
||||
require.NoError(t, err)
|
||||
p := sqlitePersistence{db: db}
|
||||
|
||||
key, err := crypto.GenerateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
contactID := types.EncodeHex(crypto.FromECDSAPub(&key.PublicKey))
|
||||
|
||||
err = p.SaveContact(&Contact{ID: contactID}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
jpegType := []byte{0xff, 0xd8, 0xff, 0x1}
|
||||
identityImages := make(map[string]*protobuf.IdentityImage)
|
||||
identityImages["large"] = &protobuf.IdentityImage{
|
||||
Payload: jpegType,
|
||||
SourceType: protobuf.IdentityImage_RAW_PAYLOAD,
|
||||
ImageType: protobuf.ImageType_PNG,
|
||||
}
|
||||
|
||||
identityImages["small"] = &protobuf.IdentityImage{
|
||||
Payload: jpegType,
|
||||
SourceType: protobuf.IdentityImage_RAW_PAYLOAD,
|
||||
ImageType: protobuf.ImageType_PNG,
|
||||
}
|
||||
|
||||
images := &protobuf.ChatIdentity{
|
||||
Clock: 1,
|
||||
Images: identityImages,
|
||||
}
|
||||
|
||||
result, err := p.SaveContactChatIdentity(contactID, images)
|
||||
require.NoError(t, err)
|
||||
require.True(t, result)
|
||||
|
||||
// Save again same clock, it should return false
|
||||
result, err = p.SaveContactChatIdentity(contactID, images)
|
||||
require.NoError(t, err)
|
||||
require.False(t, result)
|
||||
|
||||
contacts, err := p.Contacts()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, contacts, 1)
|
||||
|
||||
require.Len(t, contacts[0].Images, 2)
|
||||
}
|
||||
|
||||
func TestSaveLinks(t *testing.T) {
|
||||
chatID := testPublicChatID
|
||||
db, err := openTestDB()
|
||||
|
|
Loading…
Reference in New Issue