Skip to content

Commit a89604d

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 09fbe78 commit a89604d

File tree

13 files changed

+200
-13
lines changed

13 files changed

+200
-13
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: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ var (
5050
DisplayAssetsBelowBalance: false,
5151
ShowCommunityAssetWhenSendingTokens: true,
5252
NewsFeedEnabled: true,
53+
NewsRSSEnabled: true,
5354
}
5455
)
5556

@@ -244,10 +245,10 @@ func TestDatabase_NewsFeedEnabled(t *testing.T) {
244245

245246
require.NoError(t, db.CreateSettings(settings, config))
246247

247-
settings, err := db.GetSettings()
248+
enabled, err := db.NewsFeedEnabled()
248249
require.NoError(t, err)
249250

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

252253
err = db.SaveSetting(NewsFeedEnabled.GetReactName(), false)
253254
require.NoError(t, err)
@@ -263,11 +264,11 @@ func TestDatabase_NewsFeedLastFetchedTimestamp(t *testing.T) {
263264

264265
require.NoError(t, db.CreateSettings(settings, config))
265266

266-
settings, err := db.GetSettings()
267+
timestamp, err := db.NewsFeedLastFetchedTimestamp()
267268
require.NoError(t, err)
268269

269270
// 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())
271+
require.GreaterOrEqual(t, time.Now().UTC().Second(), timestamp.UTC().Second())
271272

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

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
@@ -915,8 +915,13 @@ func (m *Messenger) Start() (*MessengerResponse, error) {
915915
newsfeed.WithFetchFrom(lastFetched),
916916
)
917917

918-
// TODO only start if the setting is enabled
919-
m.newsFeedManager.StartFetching(m.ctx)
918+
newsFeedEnabled, err := m.IsNewsFeedEnabled()
919+
if err != nil {
920+
return nil, err
921+
}
922+
if newsFeedEnabled {
923+
m.newsFeedManager.StartPolling(m.ctx)
924+
}
920925
}
921926

922927
return response, nil

protocol/messenger_news_feed.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,54 @@ 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+
return m.changeNewsFeedManagerAfterUpdate()
136+
}
137+
138+
func (m *Messenger) ToggleNewsRSSEnabled(value bool) error {
139+
err := m.settings.SaveSetting(settings.NewsRSSEnabled.GetReactName(), value)
140+
if err != nil {
141+
return err
142+
}
143+
return m.changeNewsFeedManagerAfterUpdate()
144+
}

protocol/messenger_news_feed_test.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"testing"
55
"time"
66

7-
"github.com/stretchr/testify/suite"
8-
97
"github.com/brianvoe/gofakeit/v6"
108
"github.com/mmcdole/gofeed"
9+
"github.com/stretchr/testify/suite"
10+
11+
"github.com/status-im/status-go/internal/newsfeed"
1112
)
1213

1314
type MessengerNewsFeedSuite struct {
@@ -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,31 @@ 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+
err := s.m.ToggleNewsFeedEnabled(true)
70+
s.Require().NoError(err)
71+
s.Require().True(s.m.newsFeedManager.IsPolling())
72+
73+
// Polling is off as soon as one setting is off
74+
err = s.m.ToggleNewsFeedEnabled(false)
75+
s.Require().NoError(err)
76+
s.Require().False(s.m.newsFeedManager.IsPolling())
77+
78+
err = s.m.ToggleNewsRSSEnabled(false)
79+
s.Require().NoError(err)
80+
s.Require().False(s.m.newsFeedManager.IsPolling())
81+
82+
//Poolling is still off
83+
err = s.m.ToggleNewsRSSEnabled(true)
84+
s.Require().NoError(err)
85+
s.Require().False(s.m.newsFeedManager.IsPolling())
86+
87+
// Polling restart if both settings are on
88+
err = s.m.ToggleNewsFeedEnabled(true)
89+
s.Require().NoError(err)
90+
s.Require().True(s.m.newsFeedManager.IsPolling())
91+
92+
s.m.newsFeedManager.StopPolling()
93+
s.Require().False(s.m.newsFeedManager.IsPolling())
94+
}

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)