status-go/multiaccounts/settings/structs.go

241 lines
12 KiB
Go

package settings
import (
"encoding/json"
"reflect"
accountJson "github.com/status-im/status-go/account/json"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/protobuf"
)
type ValueHandler func(interface{}) (interface{}, error)
type ValueCastHandler func(interface{}) (interface{}, error)
type SyncSettingProtobufFactoryInterface func(interface{}, uint64, string) (*common.RawMessage, *protobuf.SyncSetting, error)
type SyncSettingProtobufFactoryStruct func(Settings, uint64, string) (*common.RawMessage, *protobuf.SyncSetting, error)
type SyncSettingProtobufToValue func(setting *protobuf.SyncSetting) interface{}
// SyncProtobufFactory represents a collection of functionality to generate and parse *protobuf.SyncSetting
type SyncProtobufFactory struct {
inactive bool
fromInterface SyncSettingProtobufFactoryInterface
fromStruct SyncSettingProtobufFactoryStruct
valueFromProtobuf SyncSettingProtobufToValue
protobufType protobuf.SyncSetting_Type
}
func (spf *SyncProtobufFactory) Inactive() bool {
return spf.inactive
}
func (spf *SyncProtobufFactory) FromInterface() SyncSettingProtobufFactoryInterface {
return spf.fromInterface
}
func (spf *SyncProtobufFactory) FromStruct() SyncSettingProtobufFactoryStruct {
return spf.fromStruct
}
func (spf *SyncProtobufFactory) ExtractValueFromProtobuf() SyncSettingProtobufToValue {
return spf.valueFromProtobuf
}
func (spf *SyncProtobufFactory) SyncSettingProtobufType() protobuf.SyncSetting_Type {
return spf.protobufType
}
// SyncSettingField represents a binding between a Value and a SettingField
type SyncSettingField struct {
SettingField
Value interface{}
}
func (s SyncSettingField) MarshalJSON() ([]byte, error) {
alias := struct {
Name string `json:"name"`
Value interface{} `json:"value"`
}{
s.reactFieldName,
s.Value,
}
return json.Marshal(alias)
}
// SettingField represents an individual setting in the database, it contains context dependant names and optional
// pre-store value parsing, along with optional *SyncProtobufFactory
type SettingField struct {
reactFieldName string
dBColumnName string
valueHandler ValueHandler
syncProtobufFactory *SyncProtobufFactory
valueCastHandler ValueCastHandler
}
func (s SettingField) GetReactName() string {
return s.reactFieldName
}
func (s SettingField) GetDBName() string {
return s.dBColumnName
}
func (s SettingField) ValueHandler() ValueHandler {
return s.valueHandler
}
func (s SettingField) ValueCastHandler() ValueCastHandler {
return s.valueCastHandler
}
func (s SettingField) SyncProtobufFactory() *SyncProtobufFactory {
return s.syncProtobufFactory
}
// CanSync checks if a SettingField has functions supporting the syncing of
func (s SettingField) CanSync(source SyncSource) bool {
spf := s.syncProtobufFactory
if spf == nil {
return false
}
if spf.inactive {
return false
}
switch source {
case FromInterface:
return spf.fromInterface != nil
case FromStruct:
return spf.fromStruct != nil
default:
return false
}
}
func (s SettingField) Equals(other SettingField) bool {
return s.reactFieldName == other.reactFieldName
}
// Settings represents the entire setting row stored in the application db
type Settings struct {
// required
Address types.Address `json:"address"`
AnonMetricsShouldSend bool `json:"anon-metrics/should-send?,omitempty"`
ChaosMode bool `json:"chaos-mode?,omitempty"`
Currency string `json:"currency,omitempty"`
CurrentNetwork string `json:"networks/current-network"`
CustomBootnodes *json.RawMessage `json:"custom-bootnodes,omitempty"`
CustomBootnodesEnabled *json.RawMessage `json:"custom-bootnodes-enabled?,omitempty"`
DappsAddress types.Address `json:"dapps-address"`
DeviceName string `json:"device-name"`
DisplayName string `json:"display-name"`
Bio string `json:"bio,omitempty"`
EIP1581Address types.Address `json:"eip1581-address"`
Fleet *string `json:"fleet,omitempty"`
HideHomeTooltip bool `json:"hide-home-tooltip?,omitempty"`
InstallationID string `json:"installation-id"`
KeyUID string `json:"key-uid"`
KeycardInstanceUID string `json:"keycard-instance-uid,omitempty"`
KeycardPairedOn int64 `json:"keycard-paired-on,omitempty"`
KeycardPairing string `json:"keycard-pairing,omitempty"`
LastUpdated *int64 `json:"last-updated,omitempty"`
LatestDerivedPath uint `json:"latest-derived-path"`
LinkPreviewRequestEnabled bool `json:"link-preview-request-enabled,omitempty"`
LinkPreviewsEnabledSites *json.RawMessage `json:"link-previews-enabled-sites,omitempty"`
LogLevel *string `json:"log-level,omitempty"`
MessagesFromContactsOnly bool `json:"messages-from-contacts-only"`
Mnemonic *string `json:"mnemonic,omitempty"`
// NOTE(rasom): negation here because it safer/simpler to have false by default
MnemonicWasNotShown bool `json:"mnemonic-was-not-shown?,omitempty"`
MnemonicRemoved bool `json:"mnemonic-removed?,omitempty"`
OmitTransfersHistoryScan bool `json:"omit-transfers-history-scan?,omitempty"`
MutualContactEnabled bool `json:"mutual-contact-enabled?"`
Name string `json:"name,omitempty"`
Networks *json.RawMessage `json:"networks/networks"`
// NotificationsEnabled indicates whether local notifications should be enabled (android only)
NotificationsEnabled bool `json:"notifications-enabled?,omitempty"`
PhotoPath string `json:"photo-path"`
PinnedMailserver *json.RawMessage `json:"pinned-mailservers,omitempty"`
PreferredName *string `json:"preferred-name,omitempty"`
PreviewPrivacy bool `json:"preview-privacy?"`
PublicKey string `json:"public-key"`
// PushNotificationsServerEnabled indicates whether we should be running a push notification server
PushNotificationsServerEnabled bool `json:"push-notifications-server-enabled?,omitempty"`
// PushNotificationsFromContactsOnly indicates whether we should only receive push notifications from contacts
PushNotificationsFromContactsOnly bool `json:"push-notifications-from-contacts-only?,omitempty"`
// PushNotificationsBlockMentions indicates whether we should receive notifications for mentions
PushNotificationsBlockMentions bool `json:"push-notifications-block-mentions?,omitempty"`
RememberSyncingChoice bool `json:"remember-syncing-choice?,omitempty"`
// RemotePushNotificationsEnabled indicates whether we should be using remote notifications (ios only for now)
RemotePushNotificationsEnabled bool `json:"remote-push-notifications-enabled?,omitempty"`
SigningPhrase string `json:"signing-phrase"`
StickerPacksInstalled *json.RawMessage `json:"stickers/packs-installed,omitempty"`
StickerPacksPending *json.RawMessage `json:"stickers/packs-pending,omitempty"`
StickersRecentStickers *json.RawMessage `json:"stickers/recent-stickers,omitempty"`
SyncingOnMobileNetwork bool `json:"syncing-on-mobile-network?,omitempty"`
// DefaultSyncPeriod is how far back in seconds we should pull messages from a mailserver
DefaultSyncPeriod uint `json:"default-sync-period"`
// SendPushNotifications indicates whether we should send push notifications for other clients
SendPushNotifications bool `json:"send-push-notifications?,omitempty"`
Appearance uint `json:"appearance"`
// ProfilePicturesShowTo indicates to whom the user shows their profile picture to (contacts, everyone)
ProfilePicturesShowTo ProfilePicturesShowToType `json:"profile-pictures-show-to"`
// ProfilePicturesVisibility indicates who we want to see profile pictures of (contacts, everyone or none)
ProfilePicturesVisibility ProfilePicturesVisibilityType `json:"profile-pictures-visibility"`
UseMailservers bool `json:"use-mailservers?"`
Usernames *json.RawMessage `json:"usernames,omitempty"`
WalletRootAddress types.Address `json:"wallet-root-address,omitempty"`
WalletSetUpPassed bool `json:"wallet-set-up-passed?,omitempty"`
WalletVisibleTokens *json.RawMessage `json:"wallet/visible-tokens,omitempty"`
WakuBloomFilterMode bool `json:"waku-bloom-filter-mode,omitempty"`
WebViewAllowPermissionRequests bool `json:"webview-allow-permission-requests?,omitempty"`
SendStatusUpdates bool `json:"send-status-updates?,omitempty"`
CurrentUserStatus *json.RawMessage `json:"current-user-status"`
GifRecents *json.RawMessage `json:"gifs/recent-gifs"`
GifFavorites *json.RawMessage `json:"gifs/favorite-gifs"`
OpenseaEnabled bool `json:"opensea-enabled?,omitempty"`
TelemetryServerURL string `json:"telemetry-server-url,omitempty"`
LastBackup uint64 `json:"last-backup,omitempty"`
BackupEnabled bool `json:"backup-enabled?,omitempty"`
AutoMessageEnabled bool `json:"auto-message-enabled?,omitempty"`
GifAPIKey string `json:"gifs/api-key"`
TestNetworksEnabled bool `json:"test-networks-enabled?,omitempty"`
ProfileMigrationNeeded bool `json:"profile-migration-needed,omitempty"`
IsGoerliEnabled bool `json:"is-goerli-enabled?,omitempty"`
TokenGroupByCommunity bool `json:"token-group-by-community?,omitempty"`
ShowCommunityAssetWhenSendingTokens bool `json:"show-community-asset-when-sending-tokens?,omitempty"`
DisplayAssetsBelowBalance bool `json:"display-assets-below-balance?,omitempty"`
DisplayAssetsBelowBalanceThreshold int64 `json:"display-assets-below-balance-threshold,omitempty"`
CollectibleGroupByCollection bool `json:"collectible-group-by-collection?,omitempty"`
CollectibleGroupByCommunity bool `json:"collectible-group-by-community?,omitempty"`
URLUnfurlingMode URLUnfurlingModeType `json:"url-unfurling-mode,omitempty"`
}
func (s Settings) MarshalJSON() ([]byte, error) {
// We need this typedef in order to overcome stack overflow
// when marshaling JSON
type Alias Settings
ext, err := accountJson.ExtendStructWithPubKeyData(s.PublicKey, Alias(s))
if err != nil {
return nil, err
}
return json.Marshal(ext)
}
func (s Settings) IsEmpty() bool {
empty := reflect.Zero(reflect.TypeOf(s)).Interface()
return reflect.DeepEqual(s, empty)
}
func (s Settings) GetFleet() string {
if s.Fleet == nil {
return params.FleetUndefined
}
return *s.Fleet
}