Skip to content

Commit e62ea86

Browse files
committed
feat(news)_: hook News settings to the newsFeedManager and its polling
Needed for status-im/status-desktop#17811 Adds the NewsRSSEnabled setting that is going to be used in the Privacy settings of the clients. Adds API methods to toggle the NewsFeedEnabled and NewsRSSEnabled settings. By doing so, it will trigger the NewsFeedManager polling if both settings are set to true. Conversely, if one of them is disabled, it stops the polling.
1 parent 5f0ed7b commit e62ea86

File tree

13 files changed

+194
-11
lines changed

13 files changed

+194
-11
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE settings ADD COLUMN news_rss_enabled BOOLEAN DEFAULT TRUE;

internal/newsfeed/new_feed_manager_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,13 @@ func (s *NewsFeedManagerSuite) TestStartAndStopFetching() {
149149
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
150150
defer cancel()
151151

152-
newsFeedManager.StartFetching(ctx)
152+
newsFeedManager.StartPolling(ctx)
153153

154154
time.Sleep(1 * time.Millisecond) // Leave time for the go routine to run and process
155155

156156
// The start fetching does an initial fetch immediately
157157
s.Require().Len(captured, 1)
158158
s.Require().Equal("New Item", captured[0].Title)
159159

160-
newsFeedManager.StopFetching()
160+
newsFeedManager.StopPolling()
161161
}

internal/newsfeed/news_feed_manager.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type NewsFeedManager struct {
2727
handler FeedHandler
2828
fetchFrom time.Time
2929
pollingInterval time.Duration
30+
polling bool
3031
cancel context.CancelFunc
3132
logger *zap.Logger
3233
}
@@ -73,6 +74,7 @@ func NewNewsFeedManager(opts ...Option) *NewsFeedManager {
7374
nfm := &NewsFeedManager{
7475
pollingInterval: time.Minute * 30,
7576
fetchFrom: time.Now(),
77+
polling: false,
7678
}
7779

7880
for _, opt := range opts {
@@ -122,7 +124,16 @@ func (n *NewsFeedManager) fetchRSSAndHandle() error {
122124
return nil
123125
}
124126

125-
func (n *NewsFeedManager) StartFetching(ctx context.Context) {
127+
func (n *NewsFeedManager) IsPolling() bool {
128+
return n.polling
129+
}
130+
131+
func (n *NewsFeedManager) StartPolling(ctx context.Context) {
132+
if n.polling {
133+
return
134+
}
135+
n.polling = true
136+
126137
// Derive the given context, save the CancelFunc
127138
ctx, n.cancel = context.WithCancel(ctx)
128139

@@ -145,6 +156,10 @@ func (n *NewsFeedManager) StartFetching(ctx context.Context) {
145156
}()
146157
}
147158

148-
func (n *NewsFeedManager) StopFetching() {
159+
func (n *NewsFeedManager) StopPolling() {
160+
if !n.polling {
161+
return
162+
}
149163
n.cancel()
164+
n.polling = false
150165
}

multiaccounts/settings/columns.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,11 @@ var (
242242
dBColumnName: "news_notifications_enabled",
243243
valueHandler: BoolHandler,
244244
}
245+
NewsRSSEnabled = SettingField{
246+
reactFieldName: "news-rss-enabled?",
247+
dBColumnName: "news_rss_enabled",
248+
valueHandler: BoolHandler,
249+
}
245250
NodeConfig = SettingField{
246251
reactFieldName: "node-config",
247252
dBColumnName: "node_config",
@@ -582,6 +587,7 @@ var (
582587
NewsFeedEnabled,
583588
NewsFeedLastFetchedTimestamp,
584589
NewsNotificationsEnabled,
590+
NewsRSSEnabled,
585591
MessengerNotificationsEnabled,
586592
NodeConfig,
587593
NotificationsEnabled,

multiaccounts/settings/database.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ func (db *Database) GetSettings() (Settings, error) {
396396
test_networks_enabled, mutual_contact_enabled, profile_migration_needed, wallet_token_preferences_group_by_community, url_unfurling_mode,
397397
mnemonic_was_not_shown, wallet_show_community_asset_when_sending_tokens, wallet_display_assets_below_balance,
398398
wallet_display_assets_below_balance_threshold, wallet_collectible_preferences_group_by_collection, wallet_collectible_preferences_group_by_community,
399-
peer_syncing_enabled, auto_refresh_tokens_enabled, last_tokens_update, news_feed_enabled, news_feed_last_fetched_timestamp
399+
peer_syncing_enabled, auto_refresh_tokens_enabled, last_tokens_update, news_feed_enabled, news_feed_last_fetched_timestamp, news_rss_enabled
400400
FROM
401401
settings
402402
WHERE
@@ -485,6 +485,7 @@ func (db *Database) GetSettings() (Settings, error) {
485485
&lastTokensUpdate,
486486
&s.NewsFeedEnabled,
487487
&newsFeedLastFetchedTimestamp,
488+
&s.NewsRSSEnabled,
488489
)
489490

490491
if err != nil {
@@ -902,3 +903,27 @@ func (db *Database) NewsFeedLastFetchedTimestamp() (result time.Time, err error)
902903
}
903904
return
904905
}
906+
907+
func (db *Database) NewsFeedEnabled() (result bool, err error) {
908+
err = db.makeSelectRow(NewsFeedEnabled).Scan(&result)
909+
if err == sql.ErrNoRows {
910+
return result, nil
911+
}
912+
return result, err
913+
}
914+
915+
func (db *Database) NewsNotificationsEnabled() (result bool, err error) {
916+
err = db.makeSelectRow(NewsNotificationsEnabled).Scan(&result)
917+
if err == sql.ErrNoRows {
918+
return result, nil
919+
}
920+
return result, err
921+
}
922+
923+
func (db *Database) NewsRSSEnabled() (result bool, err error) {
924+
err = db.makeSelectRow(NewsRSSEnabled).Scan(&result)
925+
if err == sql.ErrNoRows {
926+
return result, nil
927+
}
928+
return result, err
929+
}

multiaccounts/settings/database_settings_manager.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,7 @@ type DatabaseSettingsManager interface {
8484
AutoRefreshTokensEnabled() (result bool, err error)
8585
LastTokensUpdate() (result time.Time, err error)
8686
NewsFeedLastFetchedTimestamp() (result time.Time, err error)
87+
NewsFeedEnabled() (result bool, err error)
88+
NewsNotificationsEnabled() (result bool, err error)
89+
NewsRSSEnabled() (result bool, err error)
8790
}

multiaccounts/settings/database_test.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,10 @@ func TestDatabase_NewsFeedEnabled(t *testing.T) {
244244

245245
require.NoError(t, db.CreateSettings(settings, config))
246246

247-
settings, err := db.GetSettings()
247+
enabled, err := db.NewsFeedEnabled()
248248
require.NoError(t, err)
249249

250-
require.Equal(t, true, settings.NewsFeedEnabled)
250+
require.Equal(t, true, enabled)
251251

252252
err = db.SaveSetting(NewsFeedEnabled.GetReactName(), false)
253253
require.NoError(t, err)
@@ -263,11 +263,11 @@ func TestDatabase_NewsFeedLastFetchedTimestamp(t *testing.T) {
263263

264264
require.NoError(t, db.CreateSettings(settings, config))
265265

266-
settings, err := db.GetSettings()
266+
timestamp, err := db.NewsFeedLastFetchedTimestamp()
267267
require.NoError(t, err)
268268

269269
// Using GreaterOrEqual because the timestamp is set during CreateSettings and there is a tiny chance that the second changes between
270-
require.GreaterOrEqual(t, time.Now().UTC().Second(), settings.NewsFeedLastFetchedTimestamp.UTC().Second())
270+
require.GreaterOrEqual(t, time.Now().UTC().Second(), timestamp.UTC().Second())
271271

272272
dateNow := time.Now()
273273
err = db.SaveSetting(NewsFeedLastFetchedTimestamp.GetReactName(), dateNow)
@@ -277,3 +277,22 @@ func TestDatabase_NewsFeedLastFetchedTimestamp(t *testing.T) {
277277
require.NoError(t, err)
278278
require.Equal(t, dateNow.UTC().Second(), settings.NewsFeedLastFetchedTimestamp.UTC().Second())
279279
}
280+
281+
func TestDatabase_NewsRSSEnabled(t *testing.T) {
282+
db, stop := setupTestDB(t)
283+
defer stop()
284+
285+
require.NoError(t, db.CreateSettings(settings, config))
286+
287+
enabled, err := db.NewsRSSEnabled()
288+
require.NoError(t, err)
289+
290+
require.Equal(t, true, enabled)
291+
292+
err = db.SaveSetting(NewsRSSEnabled.GetReactName(), false)
293+
require.NoError(t, err)
294+
295+
settings, err = db.GetSettings()
296+
require.NoError(t, err)
297+
require.Equal(t, false, settings.NewsRSSEnabled)
298+
}

multiaccounts/settings/structs.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ type Settings struct {
161161
NewsFeedEnabled bool `json:"news-feed-enabled?,omitempty"`
162162
NewsFeedLastFetchedTimestamp time.Time `json:"news-feed-last-fetched-timestamp,omitempty"`
163163
NewsNotificationsEnabled bool `json:"news-notifications-enabled?,omitempty"`
164+
NewsRSSEnabled bool `json:"news-rss-enabled?,omitempty"`
164165
PhotoPath string `json:"photo-path"`
165166
PinnedMailserver *json.RawMessage `json:"pinned-mailservers,omitempty"`
166167
// PreferredName represents the user's preferred Ethereum Name Service (ENS) name.

protocol/messenger.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,13 @@ func (m *Messenger) Start() (*MessengerResponse, error) {
921921
newsfeed.WithFetchFrom(lastFetched),
922922
)
923923

924-
// TODO only start if the setting is enabled
925-
m.newsFeedManager.StartFetching(m.ctx)
924+
newsFeedEnabled, err := m.IsNewsFeedEnabled()
925+
if err != nil {
926+
return nil, err
927+
}
928+
if newsFeedEnabled {
929+
m.newsFeedManager.StartPolling(m.ctx)
930+
}
926931
}
927932

928933
return response, nil

protocol/messenger_news_feed.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,56 @@ func (m *Messenger) FetchNewsMessages() (*MessengerResponse, error) {
9191
}
9292
return response, nil
9393
}
94+
95+
// The News Feed is enabled if both:
96+
// 1. The News Feed is enabled in the settings.
97+
// 2. The RSS feed is enabled in the settings.
98+
func (m *Messenger) IsNewsFeedEnabled() (bool, error) {
99+
newsFeedEnabled, err := m.settings.NewsFeedEnabled()
100+
if err != nil {
101+
return false, err
102+
}
103+
if !newsFeedEnabled {
104+
return false, nil
105+
}
106+
newsRSSEnabled, err := m.settings.NewsRSSEnabled()
107+
if err != nil {
108+
return false, err
109+
}
110+
return newsRSSEnabled, nil
111+
}
112+
113+
func (m *Messenger) changeNewsFeedManagerAfterUpdate() error {
114+
if m.newsFeedManager == nil {
115+
return nil
116+
}
117+
isNewsFeedEnabled, err := m.IsNewsFeedEnabled()
118+
if err != nil {
119+
return err
120+
}
121+
122+
if isNewsFeedEnabled {
123+
m.newsFeedManager.StartPolling(m.ctx)
124+
} else {
125+
m.newsFeedManager.StopPolling()
126+
}
127+
return nil
128+
}
129+
130+
func (m *Messenger) ToggleNewsFeedEnabled(value bool) error {
131+
err := m.settings.SaveSetting(settings.NewsFeedEnabled.GetReactName(), value)
132+
if err != nil {
133+
return err
134+
}
135+
m.changeNewsFeedManagerAfterUpdate()
136+
return nil
137+
}
138+
139+
func (m *Messenger) ToggleNewsRSSEnabled(value bool) error {
140+
err := m.settings.SaveSetting(settings.NewsRSSEnabled.GetReactName(), value)
141+
if err != nil {
142+
return err
143+
}
144+
m.changeNewsFeedManagerAfterUpdate()
145+
return nil
146+
}

protocol/messenger_news_feed_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55
"time"
66

7+
"github.com/status-im/status-go/internal/newsfeed"
78
"github.com/stretchr/testify/suite"
89

910
"github.com/brianvoe/gofakeit/v6"
@@ -19,6 +20,14 @@ func (s *MessengerNewsFeedSuite) SetupTest() {
1920
s.MessengerBaseTestSuite.SetupTest()
2021

2122
s.m = s.newMessenger()
23+
s.m.newsFeedManager = newsfeed.NewNewsFeedManager(
24+
newsfeed.WithURL(newsfeed.STATUS_FEED_URL),
25+
newsfeed.WithParser(gofeed.NewParser()),
26+
newsfeed.WithHandler(s.m),
27+
newsfeed.WithLogger(s.m.logger),
28+
newsfeed.WithPollingInterval(30*time.Minute),
29+
newsfeed.WithFetchFrom(time.Now().Add(-1*time.Hour)),
30+
)
2231
}
2332

2433
func TestMessengerNewsFeedSuite(t *testing.T) {
@@ -55,3 +64,26 @@ func (s *MessengerNewsFeedSuite) TestHandleNewsFeedItem() {
5564
s.Require().Len(notifications, 1)
5665
s.Require().Equal(item.Title, notifications[0].NewsTitle)
5766
}
67+
68+
func (s *MessengerNewsFeedSuite) TestToggleSettings() {
69+
s.m.ToggleNewsFeedEnabled(true)
70+
s.Require().True(s.m.newsFeedManager.IsPolling())
71+
72+
// Polling is off as soon as one setting is off
73+
s.m.ToggleNewsFeedEnabled(false)
74+
s.Require().False(s.m.newsFeedManager.IsPolling())
75+
76+
s.m.ToggleNewsRSSEnabled(false)
77+
s.Require().False(s.m.newsFeedManager.IsPolling())
78+
79+
//Poolling is still off
80+
s.m.ToggleNewsRSSEnabled(true)
81+
s.Require().False(s.m.newsFeedManager.IsPolling())
82+
83+
// Polling restart if both settings are on
84+
s.m.ToggleNewsFeedEnabled(true)
85+
s.Require().True(s.m.newsFeedManager.IsPolling())
86+
87+
s.m.newsFeedManager.StopPolling()
88+
s.Require().False(s.m.newsFeedManager.IsPolling())
89+
}

services/accounts/settings.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ func (api *SettingsAPI) SaveNodeConfig(ctx context.Context, n *params.NodeConfig
5050
return nodecfg.SaveNodeConfig(api.db.DB(), n)
5151
}
5252

53+
// News Settings
54+
func (api *SettingsAPI) NewsFeedEnabled() (bool, error) {
55+
return api.db.NewsFeedEnabled()
56+
}
57+
58+
func (api *SettingsAPI) NewsNotificationsEnabled() (bool, error) {
59+
return api.db.NewsNotificationsEnabled()
60+
}
61+
62+
func (api *SettingsAPI) NewsRSSEnabled() (bool, error) {
63+
return api.db.NewsRSSEnabled()
64+
}
65+
5366
// Notifications Settings
5467
func (api *SettingsAPI) NotificationsGetAllowNotifications() (bool, error) {
5568
return api.db.GetAllowNotifications()

services/ext/api.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,16 @@ func (api *PublicAPI) FetchNewsMessages() (*protocol.MessengerResponse, error) {
13621362
return m.FetchNewsMessages()
13631363
}
13641364

1365+
func (api *PublicAPI) ToggleNewsFeedEnabled(value bool) error {
1366+
m := api.service.messenger
1367+
return m.ToggleNewsFeedEnabled(value)
1368+
}
1369+
1370+
func (api *PublicAPI) ToggleNewsRSSEnabled(value bool) error {
1371+
m := api.service.messenger
1372+
return m.ToggleNewsRSSEnabled(value)
1373+
}
1374+
13651375
func (api *PublicAPI) RequestAllHistoricMessages(forceFetchingBackup bool) (*protocol.MessengerResponse, error) {
13661376
return api.service.messenger.RequestAllHistoricMessages(forceFetchingBackup, false)
13671377
}

0 commit comments

Comments
 (0)