Skip to content

Commit b3de6a2

Browse files
committed
Fix search and settings (#736)
* fix search editor error cannot be entered on PC * (settings) Fix warning text display delay when selecting exchange * display a warning when the exchange settings have been changed automatically because the rate is not getted * update outdated version on workflow
1 parent 3f69fc3 commit b3de6a2

8 files changed

Lines changed: 107 additions & 26 deletions

File tree

.github/workflows/go.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
runs-on: ubuntu-20.04
77
steps:
88
- name: Check out code into the Go module directory
9-
uses: actions/checkout@v1
9+
uses: actions/checkout@v3
1010

1111
- name: Set up Go 1.21
1212
uses: actions/setup-go@v3
@@ -24,7 +24,7 @@ jobs:
2424
cp "./libwallet/instantswap/instant_example.json" "./libwallet/instantswap/instant.json"
2525
2626
- name: Cache (dependencies)
27-
uses: actions/cache@v1
27+
uses: actions/cache@v4
2828
id: cache
2929
with:
3030
path: ~/go/pkg/mod

libwallet/ext/rate_source.go

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -125,36 +125,44 @@ type RateSource interface {
125125
ToggleSource(newSource string) error
126126
AddRateListener(listener *RateListener, uniqueIdentifier string) error
127127
RemoveRateListener(uniqueIdentifier string)
128+
AddWarningMsgListener(listener *WarningMsgListener, uniqueIdentifier string) error
129+
RemoveWarningMsgListener(uniqueIdentifier string)
128130
IsRateListenerExist(uniqueIdentifier string) bool
131+
IsWarningMsgListenerExist(uniqueIdentifier string) bool
129132
}
130133

131134
// RateListener listens for new tickers and rate source change notifications.
132135
type RateListener struct {
133136
OnRateUpdated func()
134137
}
135138

139+
// WarningMsgListener listens for new fetch exchange rate settings warning message.
140+
type WarningMsgListener struct {
141+
OnWarningMsgUpdated func(string)
142+
}
143+
136144
type tickerFunc func(market values.Market) (*Ticker, error)
137145

138146
// CommonRateSource is an external rate source for fiat and crypto-currency
139147
// rates. These rates are estimates and maybe be affected by server latency and
140148
// should not be used for actual buy or sell orders except to display reasonable
141149
// estimates. CommonRateSource is embedded in all of the rate sources supported.
142150
type CommonRateSource struct {
143-
ctx context.Context
144-
source string
145-
disabled bool
146-
mtx sync.RWMutex
147-
tickers map[values.Market]*Ticker
148-
refreshing bool
149-
cond *sync.Cond
150-
getTicker tickerFunc
151-
sourceChanged chan *struct{}
152-
lastUpdate time.Time
153-
151+
ctx context.Context
152+
source string
153+
disabled bool
154+
mtx sync.RWMutex
155+
tickers map[values.Market]*Ticker
156+
refreshing bool
157+
cond *sync.Cond
158+
getTicker tickerFunc
159+
sourceChanged chan *struct{}
160+
lastUpdate time.Time
154161
disableConversionExchange func()
155162

156163
notificationListenersMu sync.RWMutex
157164
ratesListeners map[string]*RateListener
165+
warningMsgListeners map[string]*WarningMsgListener
158166
}
159167

160168
// Used to initialize a rate source.
@@ -170,6 +178,7 @@ func NewCommonRateSource(ctx context.Context, source string, disableConversionEx
170178
sourceChanged: make(chan *struct{}),
171179
disableConversionExchange: disableConversionExchange,
172180
ratesListeners: make(map[string]*RateListener),
181+
warningMsgListeners: make(map[string]*WarningMsgListener),
173182
}
174183
s.getTicker = s.sourceGetTickerFunc(source)
175184
s.cond = sync.NewCond(&s.mtx)
@@ -220,6 +229,17 @@ func (cs *CommonRateSource) isDisabled() bool {
220229
return cs.disabled
221230
}
222231

232+
func (cs *CommonRateSource) AddWarningMsgListener(listener *WarningMsgListener, uniqueIdentifier string) error {
233+
if _, ok := cs.warningMsgListeners[uniqueIdentifier]; ok {
234+
return errors.New(utils.ErrListenerAlreadyExist)
235+
}
236+
237+
cs.notificationListenersMu.Lock()
238+
defer cs.notificationListenersMu.Unlock()
239+
cs.warningMsgListeners[uniqueIdentifier] = listener
240+
return nil
241+
}
242+
223243
func (cs *CommonRateSource) AddRateListener(listener *RateListener, uniqueIdentifier string) error {
224244
if _, ok := cs.ratesListeners[uniqueIdentifier]; ok {
225245
return errors.New(utils.ErrListenerAlreadyExist)
@@ -236,6 +256,17 @@ func (cs *CommonRateSource) IsRateListenerExist(uniqueIdentifier string) bool {
236256
return ok
237257
}
238258

259+
func (cs *CommonRateSource) IsWarningMsgListenerExist(uniqueIdentifier string) bool {
260+
_, ok := cs.warningMsgListeners[uniqueIdentifier]
261+
return ok
262+
}
263+
264+
func (cs *CommonRateSource) RemoveWarningMsgListener(uniqueIdentifier string) {
265+
cs.notificationListenersMu.Lock()
266+
defer cs.notificationListenersMu.Unlock()
267+
delete(cs.warningMsgListeners, uniqueIdentifier)
268+
}
269+
239270
func (cs *CommonRateSource) RemoveRateListener(uniqueIdentifier string) {
240271
cs.notificationListenersMu.Lock()
241272
defer cs.notificationListenersMu.Unlock()
@@ -250,6 +281,14 @@ func (cs *CommonRateSource) pushlishRateUpdated() {
250281
}
251282
}
252283

284+
func (cs *CommonRateSource) pushlishWarningMsgUpdated(warningMsg string) {
285+
for _, listener := range cs.warningMsgListeners {
286+
if listener.OnWarningMsgUpdated != nil {
287+
listener.OnWarningMsgUpdated(warningMsg)
288+
}
289+
}
290+
}
291+
253292
// ToggleSource changes the rate source to newSource. This method takes some
254293
// time to refresh the rates and should be executed a a goroutine.
255294
func (cs *CommonRateSource) ToggleSource(newSource string) error {
@@ -413,21 +452,24 @@ func (cs *CommonRateSource) retryGetTicker(market values.Market) (*Ticker, error
413452
}
414453
// fetch ticker from available exchanges
415454
log.Infof("fetching from other exchanges")
455+
invalidSource := cs.source
416456
for _, source := range sources {
417-
if source == cs.source {
457+
if source == invalidSource {
418458
continue
419459
}
420460
getTickerFn := cs.sourceGetTickerFunc(source)
421461
select {
422462
case <-cs.ctx.Done():
423463
log.Errorf("fetching ticker canceled: %v", cs.ctx.Err())
464+
cs.source = invalidSource
424465
return nil, cs.ctx.Err()
425466
default:
426467
log.Infof("fetching %s rate from %v", market, source)
468+
cs.source = source
427469
newTicker, err = getTickerFn(market)
428470
if err == nil {
471+
cs.pushlishWarningMsgUpdated(fmt.Sprintf(values.String(values.StrFetchRateWarningContent), invalidSource, source))
429472
log.Infof("%s is chosen", source)
430-
cs.source = source
431473
return newTicker, nil
432474
}
433475
}

ui/modal/info_modal.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ func NewErrorModal(l *load.Load, title string, clicked ClickFunc) *InfoModal {
8585
return md
8686
}
8787

88+
// NewWarningModal returns the default warning modal UI component.
89+
func NewWarningModal(l *load.Load, title string, clicked ClickFunc) *InfoModal {
90+
icon := l.Theme.Icons.OrangeAlert
91+
md := newModal(l, title, icon, clicked)
92+
md.SetContentAlignment(layout.Center, layout.Center, layout.Center)
93+
return md
94+
}
95+
8896
// DefaultClickFunc returns the default click function satisfying the positive
8997
// btn click function.
9098
func DefaultClickFunc() ClickFunc {

ui/page/settings/app_settings_page.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"github.com/crypto-power/cryptopower/app"
1818
sharedW "github.com/crypto-power/cryptopower/libwallet/assets/wallet"
19+
"github.com/crypto-power/cryptopower/libwallet/ext"
1920
libutils "github.com/crypto-power/cryptopower/libwallet/utils"
2021
"github.com/crypto-power/cryptopower/logger"
2122
"github.com/crypto-power/cryptopower/ui/cryptomaterial"
@@ -131,6 +132,35 @@ func NewAppSettingsPage(l *load.Load) *AppSettingsPage {
131132
// Part of the load.Page interface.
132133
func (pg *AppSettingsPage) OnNavigatedTo() {
133134
pg.updateSettingOptions()
135+
pg.ListenForRateWarningMsgChange()
136+
}
137+
138+
func (pg *AppSettingsPage) ListenForRateWarningMsgChange() {
139+
// add rate listener
140+
warningMsgListener := &ext.WarningMsgListener{
141+
OnWarningMsgUpdated: func(warning string) {
142+
if warning != "" {
143+
go pg.showAutoChangeRateSourceNotice(warning)
144+
}
145+
},
146+
}
147+
if !pg.AssetsManager.RateSource.IsWarningMsgListenerExist(AppSettingsPageID) {
148+
if err := pg.AssetsManager.RateSource.AddWarningMsgListener(warningMsgListener, AppSettingsPageID); err != nil {
149+
log.Error("Can't listen warning message.")
150+
}
151+
}
152+
}
153+
154+
// Show warning about fetch exchange rate setting
155+
// when exchange is changed due to unable to fetch rate
156+
func (pg *AppSettingsPage) showAutoChangeRateSourceNotice(warnMsg string) {
157+
lowStorageModal := modal.NewWarningModal(pg.Load, values.String(values.StrFetchRateWarningTitle),
158+
func(_ bool, _ *modal.InfoModal) bool {
159+
return true
160+
}).
161+
Body(warnMsg).
162+
SetPositiveButtonText(values.String(values.StrOK))
163+
pg.ParentWindow().ShowModal(lowStorageModal)
134164
}
135165

136166
// Layout draws the page UI components into the provided C
@@ -847,6 +877,8 @@ func (pg *AppSettingsPage) updatePrivacySettings() {
847877
// Part of the load.Page interface.
848878
func (pg *AppSettingsPage) OnNavigatedFrom() {
849879
utils.ZeroBytes(pg.dexSeed)
880+
// remove fetch exchange rate warning msg listener
881+
pg.AssetsManager.RateSource.RemoveWarningMsgListener(AppSettingsPageID)
850882
}
851883

852884
func (pg *AppSettingsPage) setInitialSwitchStatus(switchComponent *cryptomaterial.Switch, isChecked bool) {

ui/page/transaction/transactions_page.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -684,17 +684,10 @@ func (pg *TransactionsPage) HandleUserInteractions(gtx C) {
684684
pg.scroll.FetchScrollData(false, pg.ParentWindow(), true)
685685
}
686686

687-
for {
688-
event, ok := pg.searchEditor.Editor.Update(gtx)
689-
if !ok {
690-
break
691-
}
692-
693-
if gtx.Source.Focused(pg.searchEditor.Editor) {
694-
switch event.(type) {
695-
case widget.ChangeEvent:
696-
pg.scroll.FetchScrollData(false, pg.ParentWindow(), true)
697-
}
687+
// When focus on search editor
688+
if gtx.Source.Focused(pg.searchEditor.Editor) {
689+
if pg.searchEditor.Changed() {
690+
pg.scroll.FetchScrollData(false, pg.ParentWindow(), true)
698691
}
699692
}
700693
}

ui/preference/list_preference.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ func (lp *ListPreferenceModal) Handle(gtx C) {
194194
lp.Dismiss()
195195
}
196196

197+
lp.optionsRadioGroup.Update(gtx)
198+
197199
if lp.btnCancel.Button.Clicked(gtx) {
198200
lp.Modal.Dismiss()
199201
}

ui/values/localizable/en.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,8 @@ const EN = `
954954
"rateBinanceWarning" = "*Some countries are restricted on Binance and may not be able to fetch rate."
955955
"rateBittrexWarning" = "*Some countries are restricted on Bittrex and may not be able to fetch rate."
956956
"rateKucoinWarning" = "*Some countries are restricted on Kucoin and may not be able to fetch rate."
957+
"fetchRateWarningTitle" = "Settings Warning"
958+
"fetchRateWarningContent" = "Can't get rate ticker from %s. The settings have been changed to %s."
957959
"restrictDetail" = "Restriction Detail"
958960
"rateUnavailable" = "The rate unavailable this time, please reset it later in settings."
959961
"privacy" = "Privacy"

ui/values/strings.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,8 @@ const (
10651065
StrRateBinanceWarning = "rateBinanceWarning"
10661066
StrRateBittrexWarning = "rateBittrexWarning"
10671067
StrRateKucoinWarning = "rateKucoinWarning"
1068+
StrFetchRateWarningTitle = "fetchRateWarningTitle"
1069+
StrFetchRateWarningContent = "fetchRateWarningContent"
10681070
StrRestrictedDetail = "restrictDetail"
10691071
StrRateUnavailable = "rateUnavailable"
10701072
StrPrivacy = "privacy"

0 commit comments

Comments
 (0)