Feat: Add social links to the profile showcase (#4775)
* feat: add social links to the profile showcase * fix: deprecate old social links, add synced profile showcase to response
This commit is contained in:
parent
92bc64bb41
commit
7cc4c12642
|
@ -109,6 +109,7 @@ type Contact struct {
|
|||
// Bio - description of the contact (tell us about yourself)
|
||||
Bio string `json:"bio"`
|
||||
|
||||
// Deprecated: use social links from ProfileShowcasePreferences
|
||||
SocialLinks identity.SocialLinks `json:"socialLinks"`
|
||||
|
||||
Images map[string]images.IdentityImage `json:"images"`
|
||||
|
|
|
@ -4,6 +4,16 @@ import "errors"
|
|||
|
||||
var ErrorNoAccountProvidedWithTokenOrCollectible = errors.New("no account provided with tokens or collectible")
|
||||
|
||||
var ErrorExceedMaxProfileShowcaseCommunitiesLimit = errors.New("exeed maximum profile showcase communities limit")
|
||||
var ErrorExceedMaxProfileShowcaseAccountsLimit = errors.New("exeed maximum profile showcase accounts limit")
|
||||
var ErrorExceedMaxProfileShowcaseCollectiblesLimit = errors.New("exeed maximum profile showcase collectibles limit")
|
||||
var ErrorExceedMaxProfileShowcaseVerifiedTokensLimit = errors.New("exeed maximum profile showcase verified tokens limit")
|
||||
var ErrorExceedMaxProfileShowcaseUnverifiedTokensLimit = errors.New("exeed maximum profile showcase unverified tokens limit")
|
||||
var ErrorExceedMaxProfileShowcaseSocialLinksLimit = errors.New("exeed maximum profile showcase communities limit")
|
||||
|
||||
const maxProfileShowcaseSocialLinksLimit = 20
|
||||
const maxProfileShowcaseOtherEntriesLimit = 100
|
||||
|
||||
type ProfileShowcaseVisibility int
|
||||
|
||||
const (
|
||||
|
@ -21,6 +31,8 @@ const (
|
|||
ProfileShowcaseMembershipStatusNotAMember
|
||||
)
|
||||
|
||||
// Profile showcase preferences
|
||||
|
||||
type ProfileShowcaseCommunityPreference struct {
|
||||
CommunityID string `json:"communityId"`
|
||||
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
|
||||
|
@ -60,6 +72,13 @@ type ProfileShowcaseUnverifiedTokenPreference struct {
|
|||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
type ProfileShowcaseSocialLinkPreference struct {
|
||||
URL string `json:"url"`
|
||||
Text string `json:"text"`
|
||||
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
type ProfileShowcasePreferences struct {
|
||||
Clock uint64 `json:"clock"`
|
||||
Communities []*ProfileShowcaseCommunityPreference `json:"communities"`
|
||||
|
@ -67,8 +86,11 @@ type ProfileShowcasePreferences struct {
|
|||
Collectibles []*ProfileShowcaseCollectiblePreference `json:"collectibles"`
|
||||
VerifiedTokens []*ProfileShowcaseVerifiedTokenPreference `json:"verifiedTokens"`
|
||||
UnverifiedTokens []*ProfileShowcaseUnverifiedTokenPreference `json:"unverifiedTokens"`
|
||||
SocialLinks []*ProfileShowcaseSocialLinkPreference `json:"socialLinks"`
|
||||
}
|
||||
|
||||
// Profile showcase for a contact
|
||||
|
||||
type ProfileShowcaseCommunity struct {
|
||||
CommunityID string `json:"communityId"`
|
||||
Order int `json:"order"`
|
||||
|
@ -105,6 +127,12 @@ type ProfileShowcaseUnverifiedToken struct {
|
|||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
type ProfileShowcaseSocialLink struct {
|
||||
URL string `json:"url"`
|
||||
Text string `json:"text"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
type ProfileShowcase struct {
|
||||
ContactID string `json:"contactId"`
|
||||
Communities []*ProfileShowcaseCommunity `json:"communities"`
|
||||
|
@ -112,9 +140,29 @@ type ProfileShowcase struct {
|
|||
Collectibles []*ProfileShowcaseCollectible `json:"collectibles"`
|
||||
VerifiedTokens []*ProfileShowcaseVerifiedToken `json:"verifiedTokens"`
|
||||
UnverifiedTokens []*ProfileShowcaseUnverifiedToken `json:"unverifiedTokens"`
|
||||
SocialLinks []*ProfileShowcaseSocialLink `json:"socialLinks"`
|
||||
}
|
||||
|
||||
func Validate(preferences *ProfileShowcasePreferences) error {
|
||||
if len(preferences.Communities) > maxProfileShowcaseOtherEntriesLimit {
|
||||
return ErrorExceedMaxProfileShowcaseCommunitiesLimit
|
||||
}
|
||||
if len(preferences.Accounts) > maxProfileShowcaseOtherEntriesLimit {
|
||||
return ErrorExceedMaxProfileShowcaseAccountsLimit
|
||||
}
|
||||
if len(preferences.Collectibles) > maxProfileShowcaseOtherEntriesLimit {
|
||||
return ErrorExceedMaxProfileShowcaseCollectiblesLimit
|
||||
}
|
||||
if len(preferences.VerifiedTokens) > maxProfileShowcaseOtherEntriesLimit {
|
||||
return ErrorExceedMaxProfileShowcaseVerifiedTokensLimit
|
||||
}
|
||||
if len(preferences.UnverifiedTokens) > maxProfileShowcaseOtherEntriesLimit {
|
||||
return ErrorExceedMaxProfileShowcaseUnverifiedTokensLimit
|
||||
}
|
||||
if len(preferences.SocialLinks) > maxProfileShowcaseSocialLinksLimit {
|
||||
return ErrorExceedMaxProfileShowcaseSocialLinksLimit
|
||||
}
|
||||
|
||||
if (len(preferences.VerifiedTokens) > 0 || len(preferences.UnverifiedTokens) > 0 || len(preferences.Collectibles) > 0) &&
|
||||
len(preferences.Accounts) == 0 {
|
||||
return ErrorNoAccountProvidedWithTokenOrCollectible
|
||||
|
|
|
@ -177,6 +177,12 @@ func (m *Messenger) handleBackedUpProfile(message *protobuf.BackedUpProfile, bac
|
|||
return err
|
||||
}
|
||||
|
||||
profileShowcasePreferences, err := m.saveProfileShowcasePreferencesProto(message.ProfileShowcasePreferences, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
response.SetProfileShowcasePreferences(profileShowcasePreferences)
|
||||
|
||||
var ensUsernameDetails []*ensservice.UsernameDetail
|
||||
for _, d := range message.EnsUsernameDetails {
|
||||
dd, err := m.saveEnsUsernameDetailProto(d)
|
||||
|
|
|
@ -231,6 +231,7 @@ func (s *MessengerBackupSuite) TestBackupProfile() {
|
|||
s.Require().Len(bob2ProfileShowcasePreferences.Collectibles, 0)
|
||||
s.Require().Len(bob2ProfileShowcasePreferences.VerifiedTokens, 0)
|
||||
s.Require().Len(bob2ProfileShowcasePreferences.UnverifiedTokens, 0)
|
||||
s.Require().Len(bob2ProfileShowcasePreferences.SocialLinks, 0)
|
||||
|
||||
// Backup
|
||||
clock, err := bob1.BackupData(context.Background())
|
||||
|
|
|
@ -3930,6 +3930,7 @@ func (m *Messenger) addNewKeypairAddedOnPairedDeviceACNotification(keyUID string
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Messenger) HandleSyncProfileShowcasePreferences(state *ReceivedMessageState, p *protobuf.SyncProfileShowcasePreferences, msg *v1protocol.StatusMessage) error {
|
||||
return m.saveProfileShowcasePreferencesProto(p, false)
|
||||
func (m *Messenger) HandleSyncProfileShowcasePreferences(state *ReceivedMessageState, p *protobuf.SyncProfileShowcasePreferences, statusMessage *v1protocol.StatusMessage) error {
|
||||
_, err := m.saveProfileShowcasePreferencesProto(p, false)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -32,6 +32,12 @@ var errorNoAccountPresentedForCollectible = errors.New("account holding the coll
|
|||
var errorDublicateAccountAddress = errors.New("duplicate account address")
|
||||
var errorAccountVisibilityLowerThanCollectible = errors.New("account visibility lower than collectible")
|
||||
|
||||
func sortProfileEntyByOrder(slice interface{}, getOrder func(int) int) {
|
||||
sort.Slice(slice, func(i, j int) bool {
|
||||
return getOrder(j) > getOrder(i)
|
||||
})
|
||||
}
|
||||
|
||||
func toCollectibleUniqueID(contractAddress string, tokenID string, chainID uint64) (thirdparty.CollectibleUniqueID, error) {
|
||||
tokenIDInt := new(big.Int)
|
||||
tokenIDInt, isTokenIDOk := tokenIDInt.SetString(tokenID, 10)
|
||||
|
@ -198,6 +204,22 @@ func (m *Messenger) toProfileShowcaseUnverifiedTokensProto(preferences []*identi
|
|||
return entries
|
||||
}
|
||||
|
||||
func (m *Messenger) toProfileShowcaseSocialLinksProto(preferences []*identity.ProfileShowcaseSocialLinkPreference, visibility identity.ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseSocialLink {
|
||||
entries := []*protobuf.ProfileShowcaseSocialLink{}
|
||||
for _, preference := range preferences {
|
||||
if preference.ShowcaseVisibility != visibility {
|
||||
continue
|
||||
}
|
||||
|
||||
entries = append(entries, &protobuf.ProfileShowcaseSocialLink{
|
||||
Text: preference.Text,
|
||||
Url: preference.URL,
|
||||
Order: uint32(preference.Order),
|
||||
})
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
func (m *Messenger) fromProfileShowcaseCommunityProto(senderPubKey *ecdsa.PublicKey, messages []*protobuf.ProfileShowcaseCommunity) []*identity.ProfileShowcaseCommunity {
|
||||
entries := []*identity.ProfileShowcaseCommunity{}
|
||||
for _, message := range messages {
|
||||
|
@ -296,6 +318,18 @@ func (m *Messenger) fromProfileShowcaseUnverifiedTokenProto(messages []*protobuf
|
|||
return entries
|
||||
}
|
||||
|
||||
func (m *Messenger) fromProfileShowcaseSocialLinkProto(messages []*protobuf.ProfileShowcaseSocialLink) []*identity.ProfileShowcaseSocialLink {
|
||||
entries := []*identity.ProfileShowcaseSocialLink{}
|
||||
for _, entry := range messages {
|
||||
entries = append(entries, &identity.ProfileShowcaseSocialLink{
|
||||
Text: entry.Text,
|
||||
URL: entry.Url,
|
||||
Order: int(entry.Order),
|
||||
})
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
func (m *Messenger) SetProfileShowcasePreferences(preferences *identity.ProfileShowcasePreferences, sync bool) error {
|
||||
clock, _ := m.getLastClockWithRelatedChat()
|
||||
preferences.Clock = clock
|
||||
|
@ -450,6 +484,7 @@ func (m *Messenger) GetProfileShowcaseForSelfIdentity() (*protobuf.ProfileShowca
|
|||
Collectibles: m.toProfileShowcaseCollectibleProto(preferences.Collectibles, identity.ProfileShowcaseVisibilityEveryone),
|
||||
VerifiedTokens: m.toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, identity.ProfileShowcaseVisibilityEveryone),
|
||||
UnverifiedTokens: m.toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, identity.ProfileShowcaseVisibilityEveryone),
|
||||
SocialLinks: m.toProfileShowcaseSocialLinksProto(preferences.SocialLinks, identity.ProfileShowcaseVisibilityEveryone),
|
||||
}
|
||||
|
||||
forContacts := &protobuf.ProfileShowcaseEntries{
|
||||
|
@ -458,6 +493,7 @@ func (m *Messenger) GetProfileShowcaseForSelfIdentity() (*protobuf.ProfileShowca
|
|||
Collectibles: m.toProfileShowcaseCollectibleProto(preferences.Collectibles, identity.ProfileShowcaseVisibilityContacts),
|
||||
VerifiedTokens: m.toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, identity.ProfileShowcaseVisibilityContacts),
|
||||
UnverifiedTokens: m.toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, identity.ProfileShowcaseVisibilityContacts),
|
||||
SocialLinks: m.toProfileShowcaseSocialLinksProto(preferences.SocialLinks, identity.ProfileShowcaseVisibilityContacts),
|
||||
}
|
||||
|
||||
forIDVerifiedContacts := &protobuf.ProfileShowcaseEntries{
|
||||
|
@ -466,6 +502,7 @@ func (m *Messenger) GetProfileShowcaseForSelfIdentity() (*protobuf.ProfileShowca
|
|||
Collectibles: m.toProfileShowcaseCollectibleProto(preferences.Collectibles, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
|
||||
VerifiedTokens: m.toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
|
||||
UnverifiedTokens: m.toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
|
||||
SocialLinks: m.toProfileShowcaseSocialLinksProto(preferences.SocialLinks, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
|
||||
}
|
||||
|
||||
mutualContacts := []*Contact{}
|
||||
|
@ -498,39 +535,6 @@ func (m *Messenger) GetProfileShowcaseForSelfIdentity() (*protobuf.ProfileShowca
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) buildProfileShowcaseFromEntries(
|
||||
contactID string,
|
||||
communities []*identity.ProfileShowcaseCommunity,
|
||||
accounts []*identity.ProfileShowcaseAccount,
|
||||
collectibles []*identity.ProfileShowcaseCollectible,
|
||||
verifiedTokens []*identity.ProfileShowcaseVerifiedToken,
|
||||
unverifiedTokens []*identity.ProfileShowcaseUnverifiedToken) *identity.ProfileShowcase {
|
||||
sort.Slice(communities, func(i, j int) bool {
|
||||
return communities[j].Order > communities[i].Order
|
||||
})
|
||||
sort.Slice(accounts, func(i, j int) bool {
|
||||
return accounts[j].Order > accounts[i].Order
|
||||
})
|
||||
sort.Slice(collectibles, func(i, j int) bool {
|
||||
return collectibles[j].Order > collectibles[i].Order
|
||||
})
|
||||
sort.Slice(verifiedTokens, func(i, j int) bool {
|
||||
return verifiedTokens[j].Order > verifiedTokens[i].Order
|
||||
})
|
||||
sort.Slice(unverifiedTokens, func(i, j int) bool {
|
||||
return unverifiedTokens[j].Order > unverifiedTokens[i].Order
|
||||
})
|
||||
|
||||
return &identity.ProfileShowcase{
|
||||
ContactID: contactID,
|
||||
Communities: communities,
|
||||
Accounts: accounts,
|
||||
Collectibles: collectibles,
|
||||
VerifiedTokens: verifiedTokens,
|
||||
UnverifiedTokens: unverifiedTokens,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Messenger) BuildProfileShowcaseFromIdentity(state *ReceivedMessageState, message *protobuf.ProfileShowcase) error {
|
||||
senderPubKey := state.CurrentMessageState.PublicKey
|
||||
contactID := state.CurrentMessageState.Contact.ID
|
||||
|
@ -540,12 +544,14 @@ func (m *Messenger) BuildProfileShowcaseFromIdentity(state *ReceivedMessageState
|
|||
collectibles := []*identity.ProfileShowcaseCollectible{}
|
||||
verifiedTokens := []*identity.ProfileShowcaseVerifiedToken{}
|
||||
unverifiedTokens := []*identity.ProfileShowcaseUnverifiedToken{}
|
||||
socialLinks := []*identity.ProfileShowcaseSocialLink{}
|
||||
|
||||
communities = append(communities, m.fromProfileShowcaseCommunityProto(senderPubKey, message.ForEveryone.Communities)...)
|
||||
accounts = append(accounts, m.fromProfileShowcaseAccountProto(message.ForEveryone.Accounts)...)
|
||||
collectibles = append(collectibles, m.fromProfileShowcaseCollectibleProto(message.ForEveryone.Collectibles)...)
|
||||
verifiedTokens = append(verifiedTokens, m.fromProfileShowcaseVerifiedTokenProto(message.ForEveryone.VerifiedTokens)...)
|
||||
unverifiedTokens = append(unverifiedTokens, m.fromProfileShowcaseUnverifiedTokenProto(message.ForEveryone.UnverifiedTokens)...)
|
||||
socialLinks = append(socialLinks, m.fromProfileShowcaseSocialLinkProto(message.ForEveryone.SocialLinks)...)
|
||||
|
||||
forContacts, err := m.DecryptProfileShowcaseEntriesWithPubKey(senderPubKey, message.ForContacts)
|
||||
if err != nil {
|
||||
|
@ -558,6 +564,7 @@ func (m *Messenger) BuildProfileShowcaseFromIdentity(state *ReceivedMessageState
|
|||
collectibles = append(collectibles, m.fromProfileShowcaseCollectibleProto(forContacts.Collectibles)...)
|
||||
verifiedTokens = append(verifiedTokens, m.fromProfileShowcaseVerifiedTokenProto(forContacts.VerifiedTokens)...)
|
||||
unverifiedTokens = append(unverifiedTokens, m.fromProfileShowcaseUnverifiedTokenProto(forContacts.UnverifiedTokens)...)
|
||||
socialLinks = append(socialLinks, m.fromProfileShowcaseSocialLinkProto(forContacts.SocialLinks)...)
|
||||
}
|
||||
|
||||
forIDVerifiedContacts, err := m.DecryptProfileShowcaseEntriesWithPubKey(senderPubKey, message.ForIdVerifiedContacts)
|
||||
|
@ -571,10 +578,25 @@ func (m *Messenger) BuildProfileShowcaseFromIdentity(state *ReceivedMessageState
|
|||
collectibles = append(collectibles, m.fromProfileShowcaseCollectibleProto(forIDVerifiedContacts.Collectibles)...)
|
||||
verifiedTokens = append(verifiedTokens, m.fromProfileShowcaseVerifiedTokenProto(forIDVerifiedContacts.VerifiedTokens)...)
|
||||
unverifiedTokens = append(unverifiedTokens, m.fromProfileShowcaseUnverifiedTokenProto(forIDVerifiedContacts.UnverifiedTokens)...)
|
||||
socialLinks = append(socialLinks, m.fromProfileShowcaseSocialLinkProto(forIDVerifiedContacts.SocialLinks)...)
|
||||
}
|
||||
|
||||
newShowcase := m.buildProfileShowcaseFromEntries(
|
||||
contactID, communities, accounts, collectibles, verifiedTokens, unverifiedTokens)
|
||||
sortProfileEntyByOrder(communities, func(i int) int { return communities[i].Order })
|
||||
sortProfileEntyByOrder(accounts, func(i int) int { return accounts[i].Order })
|
||||
sortProfileEntyByOrder(collectibles, func(i int) int { return collectibles[i].Order })
|
||||
sortProfileEntyByOrder(verifiedTokens, func(i int) int { return verifiedTokens[i].Order })
|
||||
sortProfileEntyByOrder(unverifiedTokens, func(i int) int { return unverifiedTokens[i].Order })
|
||||
sortProfileEntyByOrder(socialLinks, func(i int) int { return socialLinks[i].Order })
|
||||
|
||||
newShowcase := &identity.ProfileShowcase{
|
||||
ContactID: contactID,
|
||||
Communities: communities,
|
||||
Accounts: accounts,
|
||||
Collectibles: collectibles,
|
||||
VerifiedTokens: verifiedTokens,
|
||||
UnverifiedTokens: unverifiedTokens,
|
||||
SocialLinks: socialLinks,
|
||||
}
|
||||
|
||||
oldShowcase, err := m.persistence.GetProfileShowcaseForContact(contactID)
|
||||
if err != nil {
|
||||
|
@ -646,9 +668,9 @@ func (m *Messenger) DeleteProfileShowcaseCommunity(community *communities.Commun
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Messenger) saveProfileShowcasePreferencesProto(p *protobuf.SyncProfileShowcasePreferences, shouldSync bool) error {
|
||||
func (m *Messenger) saveProfileShowcasePreferencesProto(p *protobuf.SyncProfileShowcasePreferences, shouldSync bool) (*identity.ProfileShowcasePreferences, error) {
|
||||
preferences := FromProfileShowcasePreferencesProto(p)
|
||||
return m.setProfileShowcasePreferences(preferences, shouldSync)
|
||||
return preferences, m.setProfileShowcasePreferences(preferences, shouldSync)
|
||||
}
|
||||
|
||||
func (m *Messenger) syncProfileShowcasePreferences(ctx context.Context, rawMessageHandler RawMessageHandler) error {
|
||||
|
|
|
@ -25,7 +25,7 @@ func ToProfileShowcaseCommunityPreferenceProto(p *identity.ProfileShowcaseCommun
|
|||
return &protobuf.ProfileShowcaseCommunityPreference{
|
||||
CommunityId: p.CommunityID,
|
||||
ShowcaseVisibility: protobuf.ProfileShowcaseVisibility(p.ShowcaseVisibility),
|
||||
Order: int32(p.Order),
|
||||
Order: uint32(p.Order),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ func ToProfileShowcaseAccountPreferenceProto(p *identity.ProfileShowcaseAccountP
|
|||
ColorId: p.ColorID,
|
||||
Emoji: p.Emoji,
|
||||
ShowcaseVisibility: protobuf.ProfileShowcaseVisibility(p.ShowcaseVisibility),
|
||||
Order: int32(p.Order),
|
||||
Order: uint32(p.Order),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ func ToProfileShowcaseCollectiblePreferenceProto(p *identity.ProfileShowcaseColl
|
|||
CommunityId: p.CommunityID,
|
||||
AccountAddress: p.AccountAddress,
|
||||
ShowcaseVisibility: protobuf.ProfileShowcaseVisibility(p.ShowcaseVisibility),
|
||||
Order: int32(p.Order),
|
||||
Order: uint32(p.Order),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ func ToProfileShowcaseVerifiedTokenPreferenceProto(p *identity.ProfileShowcaseVe
|
|||
return &protobuf.ProfileShowcaseVerifiedTokenPreference{
|
||||
Symbol: p.Symbol,
|
||||
ShowcaseVisibility: protobuf.ProfileShowcaseVisibility(p.ShowcaseVisibility),
|
||||
Order: int32(p.Order),
|
||||
Order: uint32(p.Order),
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ func ToProfileShowcaseUnverifiedTokenPreferenceProto(p *identity.ProfileShowcase
|
|||
ChainId: p.ChainID,
|
||||
CommunityId: p.CommunityID,
|
||||
ShowcaseVisibility: protobuf.ProfileShowcaseVisibility(p.ShowcaseVisibility),
|
||||
Order: int32(p.Order),
|
||||
Order: uint32(p.Order),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +184,40 @@ func ToProfileShowcaseUnverifiedTokensPreferenceProto(preferences []*identity.Pr
|
|||
return out
|
||||
}
|
||||
|
||||
func FromProfileShowcaseSocialLinkPreferenceProto(p *protobuf.ProfileShowcaseSocialLinkPreference) *identity.ProfileShowcaseSocialLinkPreference {
|
||||
return &identity.ProfileShowcaseSocialLinkPreference{
|
||||
Text: p.GetText(),
|
||||
URL: p.GetUrl(),
|
||||
ShowcaseVisibility: identity.ProfileShowcaseVisibility(p.ShowcaseVisibility),
|
||||
Order: int(p.Order),
|
||||
}
|
||||
}
|
||||
|
||||
func FromProfileShowcaseSocialLinksPreferencesProto(preferences []*protobuf.ProfileShowcaseSocialLinkPreference) []*identity.ProfileShowcaseSocialLinkPreference {
|
||||
out := make([]*identity.ProfileShowcaseSocialLinkPreference, 0, len(preferences))
|
||||
for _, p := range preferences {
|
||||
out = append(out, FromProfileShowcaseSocialLinkPreferenceProto(p))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func ToProfileShowcaseSocialLinkPreferenceProto(p *identity.ProfileShowcaseSocialLinkPreference) *protobuf.ProfileShowcaseSocialLinkPreference {
|
||||
return &protobuf.ProfileShowcaseSocialLinkPreference{
|
||||
Text: p.Text,
|
||||
Url: p.URL,
|
||||
ShowcaseVisibility: protobuf.ProfileShowcaseVisibility(p.ShowcaseVisibility),
|
||||
Order: uint32(p.Order),
|
||||
}
|
||||
}
|
||||
|
||||
func ToProfileShowcaseSocialLinksPreferenceProto(preferences []*identity.ProfileShowcaseSocialLinkPreference) []*protobuf.ProfileShowcaseSocialLinkPreference {
|
||||
out := make([]*protobuf.ProfileShowcaseSocialLinkPreference, 0, len(preferences))
|
||||
for _, p := range preferences {
|
||||
out = append(out, ToProfileShowcaseSocialLinkPreferenceProto(p))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func FromProfileShowcasePreferencesProto(p *protobuf.SyncProfileShowcasePreferences) *identity.ProfileShowcasePreferences {
|
||||
return &identity.ProfileShowcasePreferences{
|
||||
Clock: p.GetClock(),
|
||||
|
@ -192,6 +226,7 @@ func FromProfileShowcasePreferencesProto(p *protobuf.SyncProfileShowcasePreferen
|
|||
Collectibles: FromProfileShowcaseCollectiblesPreferencesProto(p.Collectibles),
|
||||
VerifiedTokens: FromProfileShowcaseVerifiedTokensPreferencesProto(p.VerifiedTokens),
|
||||
UnverifiedTokens: FromProfileShowcaseUnverifiedTokensPreferencesProto(p.UnverifiedTokens),
|
||||
SocialLinks: FromProfileShowcaseSocialLinksPreferencesProto(p.SocialLinks),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,5 +238,6 @@ func ToProfileShowcasePreferencesProto(p *identity.ProfileShowcasePreferences) *
|
|||
Collectibles: ToProfileShowcaseCollectiblesPreferenceProto(p.Collectibles),
|
||||
VerifiedTokens: ToProfileShowcaseVerifiedTokensPreferenceProto(p.VerifiedTokens),
|
||||
UnverifiedTokens: ToProfileShowcaseUnverifiedTokensPreferenceProto(p.UnverifiedTokens),
|
||||
SocialLinks: ToProfileShowcaseSocialLinksPreferenceProto(p.SocialLinks),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -249,6 +249,11 @@ func (s *TestMessengerProfileShowcase) TestSaveAndGetProfileShowcasePreferences(
|
|||
for i := 0; i < len(response.UnverifiedTokens); i++ {
|
||||
s.Require().Equal(*response.UnverifiedTokens[i], *request.UnverifiedTokens[i])
|
||||
}
|
||||
|
||||
s.Require().Equal(len(response.SocialLinks), len(request.SocialLinks))
|
||||
for i := 0; i < len(response.SocialLinks); i++ {
|
||||
s.Require().Equal(*response.SocialLinks[i], *request.SocialLinks[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TestMessengerProfileShowcase) TestFailToSaveProfileShowcasePreferencesWithWrongVisibility() {
|
||||
|
@ -357,6 +362,23 @@ func (s *TestMessengerProfileShowcase) TestEncryptAndDecryptProfileShowcaseEntri
|
|||
Order: 1,
|
||||
},
|
||||
},
|
||||
SocialLinks: []*protobuf.ProfileShowcaseSocialLink{
|
||||
&protobuf.ProfileShowcaseSocialLink{
|
||||
Text: identity.TwitterID,
|
||||
Url: "https://twitter.com/ethstatus",
|
||||
Order: 1,
|
||||
},
|
||||
&protobuf.ProfileShowcaseSocialLink{
|
||||
Text: identity.TwitterID,
|
||||
Url: "https://twitter.com/StatusIMBlog",
|
||||
Order: 2,
|
||||
},
|
||||
&protobuf.ProfileShowcaseSocialLink{
|
||||
Text: identity.GithubID,
|
||||
Url: "https://github.com/status-im",
|
||||
Order: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
data, err := s.m.EncryptProfileShowcaseEntriesWithContactPubKeys(entries, s.m.Contacts())
|
||||
s.Require().NoError(err)
|
||||
|
@ -401,6 +423,13 @@ func (s *TestMessengerProfileShowcase) TestEncryptAndDecryptProfileShowcaseEntri
|
|||
s.Require().Equal(entries.UnverifiedTokens[i].ChainId, entriesBack.UnverifiedTokens[i].ChainId)
|
||||
s.Require().Equal(entries.UnverifiedTokens[i].Order, entriesBack.UnverifiedTokens[i].Order)
|
||||
}
|
||||
|
||||
s.Require().Equal(len(entries.SocialLinks), len(entriesBack.SocialLinks))
|
||||
for i := 0; i < len(entriesBack.SocialLinks); i++ {
|
||||
s.Require().Equal(entries.SocialLinks[i].Text, entriesBack.SocialLinks[i].Text)
|
||||
s.Require().Equal(entries.SocialLinks[i].Url, entriesBack.SocialLinks[i].Url)
|
||||
s.Require().Equal(entries.SocialLinks[i].Order, entriesBack.SocialLinks[i].Order)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TestMessengerProfileShowcase) TestShareShowcasePreferences() {
|
||||
|
@ -499,11 +528,19 @@ func (s *TestMessengerProfileShowcase) TestShareShowcasePreferences() {
|
|||
s.Require().Equal(profileShowcase.UnverifiedTokens[1].ChainID, request.UnverifiedTokens[1].ChainID)
|
||||
s.Require().Equal(profileShowcase.UnverifiedTokens[1].Order, request.UnverifiedTokens[1].Order)
|
||||
|
||||
s.Require().Len(profileShowcase.SocialLinks, 2)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[0].Text, request.SocialLinks[0].Text)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[0].URL, request.SocialLinks[0].URL)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[0].Order, request.SocialLinks[0].Order)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[1].Text, request.SocialLinks[2].Text)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[1].URL, request.SocialLinks[2].URL)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[1].Order, request.SocialLinks[2].Order)
|
||||
|
||||
// Get summarised profile data for verified contact
|
||||
resp, err = WaitOnMessengerResponse(
|
||||
verifiedContact,
|
||||
func(r *MessengerResponse) bool {
|
||||
return len(r.updatedProfileShowcases) > 0
|
||||
return len(r.updatedProfileShowcases) > 0 && r.updatedProfileShowcases[contactID] != nil
|
||||
},
|
||||
"no messages",
|
||||
)
|
||||
|
@ -546,6 +583,17 @@ func (s *TestMessengerProfileShowcase) TestShareShowcasePreferences() {
|
|||
s.Require().Equal(profileShowcase.UnverifiedTokens[1].ContractAddress, request.UnverifiedTokens[1].ContractAddress)
|
||||
s.Require().Equal(profileShowcase.UnverifiedTokens[1].ChainID, request.UnverifiedTokens[1].ChainID)
|
||||
s.Require().Equal(profileShowcase.UnverifiedTokens[1].Order, request.UnverifiedTokens[1].Order)
|
||||
|
||||
s.Require().Len(profileShowcase.SocialLinks, 3)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[0].Text, request.SocialLinks[0].Text)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[0].URL, request.SocialLinks[0].URL)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[0].Order, request.SocialLinks[0].Order)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[1].Text, request.SocialLinks[1].Text)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[1].URL, request.SocialLinks[1].URL)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[1].Order, request.SocialLinks[1].Order)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[2].Text, request.SocialLinks[2].Text)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[2].URL, request.SocialLinks[2].URL)
|
||||
s.Require().Equal(profileShowcase.SocialLinks[2].Order, request.SocialLinks[2].Order)
|
||||
}
|
||||
|
||||
func (s *TestMessengerProfileShowcase) TestProfileShowcaseProofOfMembershipUnencryptedCommunities() {
|
||||
|
|
|
@ -333,7 +333,7 @@ func (m *Messenger) HandleSyncRawMessages(rawMessages []*protobuf.RawMessage) er
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = m.saveProfileShowcasePreferencesProto(&message, false)
|
||||
_, err = m.saveProfileShowcasePreferencesProto(&message, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -466,6 +466,26 @@ func DummyProfileShowcasePreferences(withCollectibles bool) *identity.ProfileSho
|
|||
Order: 1,
|
||||
},
|
||||
},
|
||||
SocialLinks: []*identity.ProfileShowcaseSocialLinkPreference{
|
||||
&identity.ProfileShowcaseSocialLinkPreference{
|
||||
Text: identity.TwitterID,
|
||||
URL: "https://twitter.com/ethstatus",
|
||||
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
|
||||
Order: 1,
|
||||
},
|
||||
&identity.ProfileShowcaseSocialLinkPreference{
|
||||
Text: identity.TwitterID,
|
||||
URL: "https://twitter.com/StatusIMBlog",
|
||||
ShowcaseVisibility: identity.ProfileShowcaseVisibilityIDVerifiedContacts,
|
||||
Order: 2,
|
||||
},
|
||||
&identity.ProfileShowcaseSocialLinkPreference{
|
||||
Text: identity.GithubID,
|
||||
URL: "https://github.com/status-im",
|
||||
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
|
||||
Order: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if withCollectibles {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
|||
|
||||
-- Create tables for storing social links in the prodile showcase
|
||||
CREATE TABLE profile_showcase_social_links_preferences (
|
||||
url VARCHAR NOT NULL CHECK (length(trim(url)) > 0),
|
||||
text VARCHAR NOT NULL CHECK (length(trim(text)) > 0),
|
||||
visibility INT NOT NULL DEFAULT 0,
|
||||
sort_order INT DEFAULT 0,
|
||||
PRIMARY KEY (text, url)
|
||||
);
|
||||
|
||||
CREATE TABLE profile_showcase_social_links_contacts (
|
||||
url VARCHAR NOT NULL CHECK (length(trim(url)) > 0),
|
||||
text VARCHAR NOT NULL CHECK (length(trim(text)) > 0),
|
||||
sort_order INT DEFAULT 0,
|
||||
contact_id TEXT NOT NULL,
|
||||
PRIMARY KEY (contact_id, text, url)
|
||||
);
|
||||
CREATE INDEX profile_showcase_social_links_contact_id ON profile_showcase_social_links_contacts (contact_id);
|
||||
|
||||
-- Copy existing social links to a new table
|
||||
INSERT INTO profile_showcase_social_links_preferences (text, url, sort_order)
|
||||
SELECT text, url, position
|
||||
FROM profile_social_links;
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/status-im/status-go/protocol/identity"
|
||||
)
|
||||
|
||||
// Profile showcase preferences
|
||||
const upsertProfileShowcasePreferencesQuery = "UPDATE profile_showcase_preferences SET clock=? WHERE NOT EXISTS (SELECT 1 FROM profile_showcase_preferences WHERE clock >= ?)"
|
||||
const selectProfileShowcasePreferencesQuery = "SELECT clock FROM profile_showcase_preferences"
|
||||
|
||||
|
@ -29,6 +30,11 @@ const selectProfileShowcaseVerifiedTokenPreferenceQuery = "SELECT symbol, visibi
|
|||
const upsertProfileShowcaseUnverifiedTokenPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_unverified_tokens_preferences(contract_address, chain_id, community_id, visibility, sort_order) VALUES (?, ?, ?, ?, ?)" // #nosec G101
|
||||
const selectProfileShowcaseUnverifiedTokenPreferenceQuery = "SELECT contract_address, chain_id, community_id, visibility, sort_order FROM profile_showcase_unverified_tokens_preferences" // #nosec G101
|
||||
|
||||
const upsertProfileShowcaseSocialLinkPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_social_links_preferences(url, text, visibility, sort_order) VALUES (?, ?, ?, ?)" // #nosec G101
|
||||
const selectProfileShowcaseSocialLinkPreferenceQuery = "SELECT url, text, visibility, sort_order FROM profile_showcase_social_links_preferences" // #nosec G101
|
||||
|
||||
// Profile showcase for a contact
|
||||
|
||||
const upsertContactProfileShowcaseCommunityQuery = "INSERT OR REPLACE INTO profile_showcase_communities_contacts(contact_id, community_id, sort_order) VALUES (?, ?, ?)" // #nosec G101
|
||||
const selectContactProfileShowcaseCommunityQuery = "SELECT community_id, sort_order FROM profile_showcase_communities_contacts WHERE contact_id = ?" // #nosec G101
|
||||
const removeContactProfileShowcaseCommunityQuery = "DELETE FROM profile_showcase_communities_contacts WHERE contact_id = ?" // #nosec G101
|
||||
|
@ -49,6 +55,10 @@ const upsertContactProfileShowcaseUnverifiedTokenQuery = "INSERT OR REPLACE INTO
|
|||
const selectContactProfileShowcaseUnverifiedTokenQuery = "SELECT contract_address, chain_id, community_id, sort_order FROM profile_showcase_unverified_tokens_contacts WHERE contact_id = ?" // #nosec G101
|
||||
const removeContactProfileShowcaseUnverifiedTokenQuery = "DELETE FROM profile_showcase_unverified_tokens_contacts WHERE contact_id = ?" // #nosec G101
|
||||
|
||||
const upsertContactProfileShowcaseSocialLinkQuery = "INSERT OR REPLACE INTO profile_showcase_social_links_contacts(contact_id, url, text, sort_order) VALUES (?, ?, ?, ?)" // #nosec G101
|
||||
const selectContactProfileShowcaseSocialLinkQuery = "SELECT url, text, sort_order FROM profile_showcase_social_links_contacts WHERE contact_id = ?" // #nosec G101
|
||||
const removeContactProfileShowcaseSocialLinkQuery = "DELETE FROM profile_showcase_social_links_contacts WHERE contact_id = ?" // #nosec G101
|
||||
|
||||
const selectProfileShowcaseAccountsWhichMatchTheAddress = `
|
||||
SELECT psa.*
|
||||
FROM
|
||||
|
@ -61,7 +71,7 @@ WHERE
|
|||
psa.address = ?
|
||||
`
|
||||
|
||||
// Queries for showcase preferences
|
||||
// Queries for the profile showcase preferences
|
||||
|
||||
func (db sqlitePersistence) saveProfileShowcasePreferencesClock(tx *sql.Tx, clock uint64) error {
|
||||
_, err := tx.Exec(upsertProfileShowcasePreferencesQuery, clock, clock)
|
||||
|
@ -247,18 +257,6 @@ func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenPreference(tx *sql.T
|
|||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenPreference(tx *sql.Tx, token *identity.ProfileShowcaseUnverifiedTokenPreference) error {
|
||||
_, err := tx.Exec(upsertProfileShowcaseUnverifiedTokenPreferenceQuery,
|
||||
token.ContractAddress,
|
||||
token.ChainID,
|
||||
token.CommunityID,
|
||||
token.ShowcaseVisibility,
|
||||
token.Order,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) getProfileShowcaseVerifiedTokensPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseVerifiedTokenPreference, error) {
|
||||
rows, err := tx.Query(selectProfileShowcaseVerifiedTokenPreferenceQuery)
|
||||
if err != nil {
|
||||
|
@ -285,6 +283,18 @@ func (db sqlitePersistence) getProfileShowcaseVerifiedTokensPreferences(tx *sql.
|
|||
return tokens, nil
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenPreference(tx *sql.Tx, token *identity.ProfileShowcaseUnverifiedTokenPreference) error {
|
||||
_, err := tx.Exec(upsertProfileShowcaseUnverifiedTokenPreferenceQuery,
|
||||
token.ContractAddress,
|
||||
token.ChainID,
|
||||
token.CommunityID,
|
||||
token.ShowcaseVisibility,
|
||||
token.Order,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseUnverifiedTokenPreference, error) {
|
||||
rows, err := tx.Query(selectProfileShowcaseUnverifiedTokenPreferenceQuery)
|
||||
if err != nil {
|
||||
|
@ -313,7 +323,45 @@ func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensPreferences(tx *sq
|
|||
return tokens, nil
|
||||
}
|
||||
|
||||
// Queries for contacts showcase
|
||||
func (db sqlitePersistence) saveProfileShowcaseSocialLinkPreference(tx *sql.Tx, link *identity.ProfileShowcaseSocialLinkPreference) error {
|
||||
_, err := tx.Exec(upsertProfileShowcaseSocialLinkPreferenceQuery,
|
||||
link.URL,
|
||||
link.Text,
|
||||
link.ShowcaseVisibility,
|
||||
link.Order,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) getProfileShowcaseSocialLinkPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseSocialLinkPreference, error) {
|
||||
rows, err := tx.Query(selectProfileShowcaseSocialLinkPreferenceQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
links := []*identity.ProfileShowcaseSocialLinkPreference{}
|
||||
|
||||
for rows.Next() {
|
||||
link := &identity.ProfileShowcaseSocialLinkPreference{}
|
||||
|
||||
err := rows.Scan(
|
||||
&link.URL,
|
||||
&link.Text,
|
||||
&link.ShowcaseVisibility,
|
||||
&link.Order,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
links = append(links, link)
|
||||
}
|
||||
return links, nil
|
||||
}
|
||||
|
||||
// Queries for the profile showcase for a contact
|
||||
func (db sqlitePersistence) saveProfileShowcaseCommunityContact(tx *sql.Tx, contactID string, community *identity.ProfileShowcaseCommunity) error {
|
||||
_, err := tx.Exec(upsertContactProfileShowcaseCommunityQuery,
|
||||
contactID,
|
||||
|
@ -468,18 +516,6 @@ func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenContact(tx *sql.Tx,
|
|||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenContact(tx *sql.Tx, contactID string, token *identity.ProfileShowcaseUnverifiedToken) error {
|
||||
_, err := tx.Exec(upsertContactProfileShowcaseUnverifiedTokenQuery,
|
||||
contactID,
|
||||
token.ContractAddress,
|
||||
token.ChainID,
|
||||
token.CommunityID,
|
||||
token.Order,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) getProfileShowcaseVerifiedTokensContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseVerifiedToken, error) {
|
||||
rows, err := tx.Query(selectContactProfileShowcaseVerifiedTokenQuery, contactID)
|
||||
if err != nil {
|
||||
|
@ -503,6 +539,23 @@ func (db sqlitePersistence) getProfileShowcaseVerifiedTokensContact(tx *sql.Tx,
|
|||
return tokens, nil
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) clearProfileShowcaseVerifiedTokensContact(tx *sql.Tx, contactID string) error {
|
||||
_, err := tx.Exec(removeContactProfileShowcaseVerifiedTokenQuery, contactID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenContact(tx *sql.Tx, contactID string, token *identity.ProfileShowcaseUnverifiedToken) error {
|
||||
_, err := tx.Exec(upsertContactProfileShowcaseUnverifiedTokenQuery,
|
||||
contactID,
|
||||
token.ContractAddress,
|
||||
token.ChainID,
|
||||
token.CommunityID,
|
||||
token.Order,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseUnverifiedToken, error) {
|
||||
rows, err := tx.Query(selectContactProfileShowcaseUnverifiedTokenQuery, contactID)
|
||||
if err != nil {
|
||||
|
@ -528,13 +581,52 @@ func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensContact(tx *sql.Tx
|
|||
return tokens, nil
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) clearProfileShowcaseVerifiedTokensContact(tx *sql.Tx, contactID string) error {
|
||||
_, err := tx.Exec(removeContactProfileShowcaseVerifiedTokenQuery, contactID)
|
||||
func (db sqlitePersistence) clearProfileShowcaseUnverifiedTokensContact(tx *sql.Tx, contactID string) error {
|
||||
_, err := tx.Exec(removeContactProfileShowcaseUnverifiedTokenQuery, contactID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) clearProfileShowcaseUnverifiedTokensContact(tx *sql.Tx, contactID string) error {
|
||||
_, err := tx.Exec(removeContactProfileShowcaseUnverifiedTokenQuery, contactID)
|
||||
func (db sqlitePersistence) saveProfileShowcaseSocialLinkContact(tx *sql.Tx, contactID string, link *identity.ProfileShowcaseSocialLink) error {
|
||||
_, err := tx.Exec(upsertContactProfileShowcaseSocialLinkQuery,
|
||||
contactID,
|
||||
link.URL,
|
||||
link.Text,
|
||||
link.Order,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) getProfileShowcaseSocialLinksContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseSocialLink, error) {
|
||||
rows, err := tx.Query(selectContactProfileShowcaseSocialLinkQuery, contactID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
links := []*identity.ProfileShowcaseSocialLink{}
|
||||
|
||||
for rows.Next() {
|
||||
link := &identity.ProfileShowcaseSocialLink{}
|
||||
|
||||
err := rows.Scan(
|
||||
&link.URL,
|
||||
&link.Text,
|
||||
&link.Order)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
links = append(links, link)
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return links, nil
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) clearProfileShowcaseSocialLinksContact(tx *sql.Tx, contactID string) error {
|
||||
_, err := tx.Exec(removeContactProfileShowcaseSocialLinkQuery, contactID)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -593,6 +685,13 @@ func (db sqlitePersistence) SaveProfileShowcasePreferences(preferences *identity
|
|||
}
|
||||
}
|
||||
|
||||
for _, link := range preferences.SocialLinks {
|
||||
err = db.saveProfileShowcaseSocialLinkPreference(tx, link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -656,6 +755,11 @@ func (db sqlitePersistence) GetProfileShowcasePreferences() (*identity.ProfileSh
|
|||
return nil, err
|
||||
}
|
||||
|
||||
socialLinks, err := db.getProfileShowcaseSocialLinkPreferences(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &identity.ProfileShowcasePreferences{
|
||||
Clock: clock,
|
||||
Communities: communities,
|
||||
|
@ -663,6 +767,7 @@ func (db sqlitePersistence) GetProfileShowcasePreferences() (*identity.ProfileSh
|
|||
Collectibles: collectibles,
|
||||
VerifiedTokens: verifiedTokens,
|
||||
UnverifiedTokens: unverifiedTokens,
|
||||
SocialLinks: socialLinks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -715,6 +820,13 @@ func (db sqlitePersistence) SaveProfileShowcaseForContact(showcase *identity.Pro
|
|||
}
|
||||
}
|
||||
|
||||
for _, link := range showcase.SocialLinks {
|
||||
err = db.saveProfileShowcaseSocialLinkContact(tx, showcase.ContactID, link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -757,6 +869,11 @@ func (db sqlitePersistence) GetProfileShowcaseForContact(contactID string) (*ide
|
|||
return nil, err
|
||||
}
|
||||
|
||||
socialLinks, err := db.getProfileShowcaseSocialLinksContact(tx, contactID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &identity.ProfileShowcase{
|
||||
ContactID: contactID,
|
||||
Communities: communities,
|
||||
|
@ -764,6 +881,7 @@ func (db sqlitePersistence) GetProfileShowcaseForContact(contactID string) (*ide
|
|||
Collectibles: collectibles,
|
||||
VerifiedTokens: verifiedTokens,
|
||||
UnverifiedTokens: unverifiedTokens,
|
||||
SocialLinks: socialLinks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -806,5 +924,10 @@ func (db sqlitePersistence) ClearProfileShowcaseForContact(contactID string) err
|
|||
return err
|
||||
}
|
||||
|
||||
err = db.clearProfileShowcaseSocialLinksContact(tx, contactID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -91,6 +91,26 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcasePreferences() {
|
|||
Order: 1,
|
||||
},
|
||||
},
|
||||
SocialLinks: []*identity.ProfileShowcaseSocialLinkPreference{
|
||||
&identity.ProfileShowcaseSocialLinkPreference{
|
||||
Text: identity.TwitterID,
|
||||
URL: "https://twitter.com/ethstatus",
|
||||
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
|
||||
Order: 1,
|
||||
},
|
||||
&identity.ProfileShowcaseSocialLinkPreference{
|
||||
Text: identity.TwitterID,
|
||||
URL: "https://twitter.com/StatusIMBlog",
|
||||
ShowcaseVisibility: identity.ProfileShowcaseVisibilityIDVerifiedContacts,
|
||||
Order: 2,
|
||||
},
|
||||
&identity.ProfileShowcaseSocialLinkPreference{
|
||||
Text: identity.GithubID,
|
||||
URL: "https://github.com/status-im",
|
||||
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
|
||||
Order: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err = persistence.SaveProfileShowcasePreferences(preferences)
|
||||
|
@ -123,6 +143,11 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcasePreferences() {
|
|||
for i := 0; i < len(preferences.UnverifiedTokens); i++ {
|
||||
s.Require().Equal(*preferences.UnverifiedTokens[i], *preferencesBack.UnverifiedTokens[i])
|
||||
}
|
||||
|
||||
s.Require().Equal(len(preferencesBack.SocialLinks), len(preferences.SocialLinks))
|
||||
for i := 0; i < len(preferences.SocialLinks); i++ {
|
||||
s.Require().Equal(*preferences.SocialLinks[i], *preferencesBack.SocialLinks[i])
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
|
||||
|
@ -197,6 +222,18 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
|
|||
Order: 1,
|
||||
},
|
||||
},
|
||||
SocialLinks: []*identity.ProfileShowcaseSocialLink{
|
||||
&identity.ProfileShowcaseSocialLink{
|
||||
URL: "https://status.app/",
|
||||
Text: "Status",
|
||||
Order: 1,
|
||||
},
|
||||
&identity.ProfileShowcaseSocialLink{
|
||||
URL: "https://github.com/status-im",
|
||||
Text: "Github",
|
||||
Order: 2,
|
||||
},
|
||||
},
|
||||
}
|
||||
err = persistence.SaveProfileShowcaseForContact(showcase1)
|
||||
s.Require().NoError(err)
|
||||
|
@ -249,6 +286,10 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
|
|||
for i := 0; i < len(showcase1.UnverifiedTokens); i++ {
|
||||
s.Require().Equal(*showcase1.UnverifiedTokens[i], *showcase1Back.UnverifiedTokens[i])
|
||||
}
|
||||
s.Require().Equal(len(showcase1.SocialLinks), len(showcase1Back.SocialLinks))
|
||||
for i := 0; i < len(showcase1.SocialLinks); i++ {
|
||||
s.Require().Equal(*showcase1.SocialLinks[i], *showcase1Back.SocialLinks[i])
|
||||
}
|
||||
|
||||
showcase2Back, err := persistence.GetProfileShowcaseForContact("contact_2")
|
||||
s.Require().NoError(err)
|
||||
|
@ -261,6 +302,7 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
|
|||
s.Require().Equal(0, len(showcase2Back.Accounts))
|
||||
s.Require().Equal(0, len(showcase2Back.VerifiedTokens))
|
||||
s.Require().Equal(0, len(showcase2Back.UnverifiedTokens))
|
||||
s.Require().Equal(0, len(showcase2Back.SocialLinks))
|
||||
}
|
||||
|
||||
func (s *TestProfileShowcasePersistence) TestFetchingProfileShowcaseAccountsByAddress() {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,6 +3,8 @@ syntax = "proto3";
|
|||
option go_package = "./;protobuf";
|
||||
package protobuf;
|
||||
|
||||
// Profile showcase for a contact
|
||||
|
||||
message ProfileShowcaseCommunity {
|
||||
string community_id = 1;
|
||||
uint32 order = 2;
|
||||
|
@ -39,12 +41,19 @@ message ProfileShowcaseUnverifiedToken {
|
|||
string community_id = 4;
|
||||
}
|
||||
|
||||
message ProfileShowcaseSocialLink {
|
||||
string url = 1;
|
||||
uint32 order = 2;
|
||||
string text = 3;
|
||||
}
|
||||
|
||||
message ProfileShowcaseEntries {
|
||||
repeated ProfileShowcaseCommunity communities = 1;
|
||||
repeated ProfileShowcaseAccount accounts = 2;
|
||||
repeated ProfileShowcaseCollectible collectibles = 3;
|
||||
repeated ProfileShowcaseVerifiedToken verifiedTokens = 4;
|
||||
repeated ProfileShowcaseUnverifiedToken unverifiedTokens = 5;
|
||||
repeated ProfileShowcaseVerifiedToken verified_tokens = 4;
|
||||
repeated ProfileShowcaseUnverifiedToken unverified_tokens = 5;
|
||||
repeated ProfileShowcaseSocialLink social_links = 6;
|
||||
}
|
||||
|
||||
message ProfileShowcaseEntriesEncrypted {
|
||||
|
@ -58,7 +67,7 @@ message ProfileShowcase {
|
|||
ProfileShowcaseEntriesEncrypted for_id_verified_contacts = 3;
|
||||
}
|
||||
|
||||
// Preferences
|
||||
// Profile showcase preferences
|
||||
|
||||
enum ProfileShowcaseVisibility {
|
||||
PROFILE_SHOWCASE_VISIBILITY_NO_ONE = 0;
|
||||
|
@ -70,7 +79,7 @@ enum ProfileShowcaseVisibility {
|
|||
message ProfileShowcaseCommunityPreference {
|
||||
string community_id = 1;
|
||||
ProfileShowcaseVisibility showcase_visibility = 2;
|
||||
int32 order = 3;
|
||||
uint32 order = 3;
|
||||
}
|
||||
|
||||
message ProfileShowcaseAccountPreference {
|
||||
|
@ -79,7 +88,7 @@ message ProfileShowcaseAccountPreference {
|
|||
string color_id = 3;
|
||||
string emoji = 4;
|
||||
ProfileShowcaseVisibility showcase_visibility = 5;
|
||||
int32 order = 6;
|
||||
uint32 order = 6;
|
||||
}
|
||||
|
||||
message ProfileShowcaseCollectiblePreference {
|
||||
|
@ -89,13 +98,13 @@ message ProfileShowcaseCollectiblePreference {
|
|||
string community_id = 4;
|
||||
string account_address = 5;
|
||||
ProfileShowcaseVisibility showcase_visibility = 6;
|
||||
int32 order = 7;
|
||||
uint32 order = 7;
|
||||
}
|
||||
|
||||
message ProfileShowcaseVerifiedTokenPreference {
|
||||
string symbol = 1;
|
||||
ProfileShowcaseVisibility showcase_visibility = 2;
|
||||
int32 order = 3;
|
||||
uint32 order = 3;
|
||||
}
|
||||
|
||||
message ProfileShowcaseUnverifiedTokenPreference {
|
||||
|
@ -103,7 +112,14 @@ message ProfileShowcaseUnverifiedTokenPreference {
|
|||
uint64 chain_id = 2;
|
||||
string community_id = 3;
|
||||
ProfileShowcaseVisibility showcase_visibility = 4;
|
||||
int32 order = 5;
|
||||
uint32 order = 5;
|
||||
}
|
||||
|
||||
message ProfileShowcaseSocialLinkPreference {
|
||||
string url = 1;
|
||||
string text = 2;
|
||||
uint32 order = 3;
|
||||
ProfileShowcaseVisibility showcase_visibility = 4;
|
||||
}
|
||||
|
||||
message SyncProfileShowcasePreferences {
|
||||
|
@ -113,4 +129,5 @@ message SyncProfileShowcasePreferences {
|
|||
repeated ProfileShowcaseCollectiblePreference collectibles = 4;
|
||||
repeated ProfileShowcaseVerifiedTokenPreference verified_tokens = 5;
|
||||
repeated ProfileShowcaseUnverifiedTokenPreference unverified_tokens = 6;
|
||||
repeated ProfileShowcaseSocialLinkPreference social_links = 7;
|
||||
}
|
|
@ -7,10 +7,12 @@ import (
|
|||
)
|
||||
|
||||
type BackedUpProfile struct {
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
Images []images.IdentityImage `json:"images,omitempty"`
|
||||
SocialLinks []*identity.SocialLink `json:"socialLinks,omitempty"`
|
||||
EnsUsernameDetails []*ens.UsernameDetail `json:"ensUsernameDetails,omitempty"`
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
Images []images.IdentityImage `json:"images,omitempty"`
|
||||
// Deprecated: use social links from ProfileShowcasePreferences
|
||||
SocialLinks []*identity.SocialLink `json:"socialLinks,omitempty"`
|
||||
EnsUsernameDetails []*ens.UsernameDetail `json:"ensUsernameDetails,omitempty"`
|
||||
ProfileShowcasePreferences identity.ProfileShowcasePreferences `json:"profile_showcase_preferences,omitempty"`
|
||||
}
|
||||
|
||||
func (sfwr *WakuBackedUpDataResponse) SetDisplayName(displayName string) {
|
||||
|
@ -21,6 +23,7 @@ func (sfwr *WakuBackedUpDataResponse) SetImages(images []images.IdentityImage) {
|
|||
sfwr.Profile.Images = images
|
||||
}
|
||||
|
||||
// Deprecated: use social links from ProfileShowcasePreferences
|
||||
func (sfwr *WakuBackedUpDataResponse) SetSocialLinks(socialLinks []*identity.SocialLink) {
|
||||
sfwr.Profile.SocialLinks = socialLinks
|
||||
}
|
||||
|
@ -28,3 +31,7 @@ func (sfwr *WakuBackedUpDataResponse) SetSocialLinks(socialLinks []*identity.Soc
|
|||
func (sfwr *WakuBackedUpDataResponse) SetEnsUsernameDetails(ensUsernameDetails []*ens.UsernameDetail) {
|
||||
sfwr.Profile.EnsUsernameDetails = ensUsernameDetails
|
||||
}
|
||||
|
||||
func (sfwr *WakuBackedUpDataResponse) SetProfileShowcasePreferences(profileShowcasePreferences *identity.ProfileShowcasePreferences) {
|
||||
sfwr.Profile.ProfileShowcasePreferences = *profileShowcasePreferences
|
||||
}
|
||||
|
|
|
@ -454,6 +454,11 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() {
|
|||
err = serverBackend.StatusNode().EnsService().API().Add(ctx, ensChainID, ensUsername)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// generate profile showcase preferences
|
||||
profileShowcasePreferences := protocol.DummyProfileShowcasePreferences(false)
|
||||
err = serverMessenger.SetProfileShowcasePreferences(profileShowcasePreferences, false)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// generate local deleted message
|
||||
_, err = serverMessenger.CreatePublicChat(&requests.CreatePublicChat{ID: publicChatID})
|
||||
require.NoError(s.T(), err)
|
||||
|
@ -496,10 +501,16 @@ func (s *SyncDeviceSuite) TestPairingSyncDeviceClientAsReceiver() {
|
|||
require.NoError(s.T(), err)
|
||||
require.Equal(s.T(), 1, len(bookmarks))
|
||||
require.Equal(s.T(), "status.im", bookmarks[0].Name)
|
||||
|
||||
clientSocialLinks, err := clientMessenger.GetSocialLinks()
|
||||
require.NoError(s.T(), err)
|
||||
require.Equal(s.T(), 1, len(clientSocialLinks))
|
||||
require.True(s.T(), socialLinksToAdd.Equal(clientSocialLinks))
|
||||
|
||||
clientProfileShowcasePreferences, err := clientMessenger.GetProfileShowcasePreferences()
|
||||
require.NoError(s.T(), err)
|
||||
require.True(s.T(), reflect.DeepEqual(profileShowcasePreferences, clientProfileShowcasePreferences))
|
||||
|
||||
uds, err := clientBackend.StatusNode().EnsService().API().GetEnsUsernames(ctx)
|
||||
require.NoError(s.T(), err)
|
||||
require.Equal(s.T(), 1, len(uds))
|
||||
|
|
|
@ -171,10 +171,12 @@ func (api *SettingsAPI) SetBio(bio string) error {
|
|||
return (*api.messenger).SetBio(bio)
|
||||
}
|
||||
|
||||
// Deprecated: use social links from ProfileShowcasePreferences
|
||||
func (api *SettingsAPI) GetSocialLinks() (identity.SocialLinks, error) {
|
||||
return api.db.GetSocialLinks()
|
||||
}
|
||||
|
||||
// Deprecated: use social links from ProfileShowcasePreferences
|
||||
func (api *SettingsAPI) AddOrReplaceSocialLinks(links identity.SocialLinks) error {
|
||||
for _, link := range links {
|
||||
if len(link.Text) == 0 {
|
||||
|
|
Loading…
Reference in New Issue