github.com/status-im/status-go@v1.1.0/services/wallet/community/manager.go (about)

     1  package community
     2  
     3  import (
     4  	"database/sql"
     5  	"encoding/json"
     6  
     7  	"github.com/ethereum/go-ethereum/event"
     8  	"github.com/ethereum/go-ethereum/log"
     9  	"github.com/status-im/status-go/server"
    10  	"github.com/status-im/status-go/services/wallet/thirdparty"
    11  	"github.com/status-im/status-go/services/wallet/walletevent"
    12  )
    13  
    14  // These events are used to notify the UI of state changes
    15  const (
    16  	EventCommmunityDataUpdated walletevent.EventType = "wallet-community-data-updated"
    17  )
    18  
    19  type Manager struct {
    20  	db                    *DataDB
    21  	communityInfoProvider thirdparty.CommunityInfoProvider
    22  	mediaServer           *server.MediaServer
    23  	feed                  *event.Feed
    24  }
    25  
    26  type Data struct {
    27  	ID    string `json:"id"`
    28  	Name  string `json:"name"`
    29  	Color string `json:"color"`
    30  	Image string `json:"image,omitempty"`
    31  }
    32  
    33  func NewManager(db *sql.DB, mediaServer *server.MediaServer, feed *event.Feed) *Manager {
    34  	return &Manager{
    35  		db:          NewDataDB(db),
    36  		mediaServer: mediaServer,
    37  		feed:        feed,
    38  	}
    39  }
    40  
    41  // Used to break circular dependency, call once as soon as possible after initialization
    42  func (cm *Manager) SetCommunityInfoProvider(communityInfoProvider thirdparty.CommunityInfoProvider) {
    43  	cm.communityInfoProvider = communityInfoProvider
    44  }
    45  
    46  func (cm *Manager) GetCommunityInfo(id string) (*thirdparty.CommunityInfo, *InfoState, error) {
    47  	communityInfo, state, err := cm.db.GetCommunityInfo(id)
    48  	if err != nil {
    49  		return nil, nil, err
    50  	}
    51  	if cm.mediaServer != nil && communityInfo != nil && len(communityInfo.CommunityImagePayload) > 0 {
    52  		communityInfo.CommunityImage = cm.GetCommunityImageURL(id)
    53  	}
    54  	return communityInfo, state, err
    55  }
    56  
    57  func (cm *Manager) GetCommunityID(tokenURI string) string {
    58  	return cm.communityInfoProvider.GetCommunityID(tokenURI)
    59  }
    60  
    61  func (cm *Manager) FillCollectiblesMetadata(communityID string, cs []*thirdparty.FullCollectibleData) (bool, error) {
    62  	return cm.communityInfoProvider.FillCollectiblesMetadata(communityID, cs)
    63  }
    64  
    65  func (cm *Manager) setCommunityInfo(id string, c *thirdparty.CommunityInfo) (err error) {
    66  	return cm.db.SetCommunityInfo(id, c)
    67  }
    68  
    69  func (cm *Manager) fetchCommunityInfo(communityID string, fetcher func() (*thirdparty.CommunityInfo, error)) (*thirdparty.CommunityInfo, error) {
    70  	communityInfo, err := fetcher()
    71  	if err != nil {
    72  		dbErr := cm.setCommunityInfo(communityID, nil)
    73  		if dbErr != nil {
    74  			log.Error("SetCommunityInfo failed", "communityID", communityID, "err", dbErr)
    75  		}
    76  		return nil, err
    77  	}
    78  	err = cm.setCommunityInfo(communityID, communityInfo)
    79  	return communityInfo, err
    80  }
    81  
    82  func (cm *Manager) FetchCommunityInfo(communityID string) (*thirdparty.CommunityInfo, error) {
    83  	return cm.fetchCommunityInfo(communityID, func() (*thirdparty.CommunityInfo, error) {
    84  		return cm.communityInfoProvider.FetchCommunityInfo(communityID)
    85  	})
    86  }
    87  
    88  func (cm *Manager) FetchCommunityMetadataAsync(communityID string) {
    89  	go func() {
    90  		communityInfo, err := cm.FetchCommunityMetadata(communityID)
    91  		if err != nil {
    92  			log.Error("FetchCommunityInfo failed", "communityID", communityID, "err", err)
    93  		}
    94  		cm.signalUpdatedCommunityMetadata(communityID, communityInfo)
    95  	}()
    96  }
    97  
    98  func (cm *Manager) FetchCommunityMetadata(communityID string) (*thirdparty.CommunityInfo, error) {
    99  	communityInfo, err := cm.FetchCommunityInfo(communityID)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  	_ = cm.setCommunityInfo(communityID, communityInfo)
   104  	return communityInfo, err
   105  }
   106  
   107  func (cm *Manager) GetCommunityImageURL(communityID string) string {
   108  	if cm.mediaServer != nil {
   109  		return cm.mediaServer.MakeWalletCommunityImagesURL(communityID)
   110  	}
   111  	return ""
   112  }
   113  
   114  func (cm *Manager) signalUpdatedCommunityMetadata(communityID string, communityInfo *thirdparty.CommunityInfo) {
   115  	if communityInfo == nil {
   116  		return
   117  	}
   118  	data := Data{
   119  		ID:    communityID,
   120  		Name:  communityInfo.CommunityName,
   121  		Color: communityInfo.CommunityColor,
   122  		Image: cm.GetCommunityImageURL(communityID),
   123  	}
   124  
   125  	payload, err := json.Marshal(data)
   126  	if err != nil {
   127  		log.Error("Error marshaling response: %v", err)
   128  		return
   129  	}
   130  
   131  	event := walletevent.Event{
   132  		Type:    EventCommmunityDataUpdated,
   133  		Message: string(payload),
   134  	}
   135  
   136  	cm.feed.Send(event)
   137  }