Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit dadc7ba

Browse files
authored
[newsfeed] Suppress unsightly animation edge cases when there are 0 or 1 active news items (MagicMirrorOrg#3336)
When the newsfeed module has an items list of size 1, every `updateInterval` the animation runs to transition from the active story to itself. This is unsightly. This PR suppresses that. To reproduce: configure newsfeed with a single news source, `ignoreOldItems` true, a short `updateInterval` (e.g. 3000), and a carefully-chosen small `ignoreOlderThan` lining up with the current contents of your news source.
1 parent b47600e commit dadc7ba

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ _This release is scheduled to be released on 2024-04-01._
2121
### Fixed
2222

2323
- Skip changelog requirement when running tests for dependency updates (#3320)
24+
- [newsfeed] Suppress unsightly animation cases when there are 0 or 1 active news items
25+
- [newsfeed] Always compute the feed item URL using the same helper function
2426

2527
### Deleted
2628

modules/default/newsfeed/newsfeed.js

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,27 +118,33 @@ Module.register("newsfeed", {
118118

119119
//Override template data and return whats used for the current template
120120
getTemplateData () {
121+
if (this.activeItem >= this.newsItems.length) {
122+
this.activeItem = 0;
123+
}
124+
this.activeItemCount = this.newsItems.length;
121125
// this.config.showFullArticle is a run-time configuration, triggered by optional notifications
122126
if (this.config.showFullArticle) {
127+
this.activeItemHash = this.newsItems[this.activeItem]?.hash;
123128
return {
124129
url: this.getActiveItemURL()
125130
};
126131
}
127132
if (this.error) {
133+
this.activeItemHash = undefined;
128134
return {
129135
error: this.error
130136
};
131137
}
132138
if (this.newsItems.length === 0) {
139+
this.activeItemHash = undefined;
133140
return {
134141
empty: true
135142
};
136143
}
137-
if (this.activeItem >= this.newsItems.length) {
138-
this.activeItem = 0;
139-
}
140144

141145
const item = this.newsItems[this.activeItem];
146+
this.activeItemHash = item.hash;
147+
142148
const items = this.newsItems.map(function (item) {
143149
item.publishDate = moment(new Date(item.pubdate)).fromNow();
144150
return item;
@@ -150,7 +156,7 @@ Module.register("newsfeed", {
150156
sourceTitle: item.sourceTitle,
151157
publishDate: moment(new Date(item.pubdate)).fromNow(),
152158
title: item.title,
153-
url: this.getUrlPrefix(item) + item.url,
159+
url: this.getActiveItemURL(),
154160
description: item.description,
155161
items: items
156162
};
@@ -312,8 +318,27 @@ Module.register("newsfeed", {
312318
if (this.timer) clearInterval(this.timer);
313319

314320
this.timer = setInterval(() => {
315-
this.activeItem++;
316-
this.updateDom(this.config.animationSpeed);
321+
322+
/*
323+
* When animations are enabled, don't update the DOM unless we are actually changing what we are displaying.
324+
* (Animating from a headline to itself is unsightly.)
325+
* Cases:
326+
*
327+
* Number of items | Number of items | Display
328+
* at last update | right now | Behaviour
329+
* ----------------------------------------------------
330+
* 0 | 0 | do not update
331+
* 0 | >0 | update
332+
* 1 | 0 or >1 | update
333+
* 1 | 1 | update only if item details (hash value) changed
334+
* >1 | any | update
335+
*
336+
* (N.B. We set activeItemCount and activeItemHash in getTemplateData().)
337+
*/
338+
if (this.newsItems.length !== this.activeItemCount || this.activeItemHash !== this.newsItems[0]?.hash) {
339+
this.activeItem++; // this is OK if newsItems.Length==1; getTemplateData will wrap it around
340+
this.updateDom(this.config.animationSpeed);
341+
}
317342

318343
// Broadcast NewsFeed if needed
319344
if (this.config.broadcastNewsFeeds) {

modules/default/newsfeed/newsfeedfetcher.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* MIT Licensed.
66
*/
77

8+
const crypto = require("node:crypto");
89
const stream = require("node:stream");
910
const FeedMe = require("feedme");
1011
const iconv = require("iconv-lite");
@@ -67,7 +68,8 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings
6768
description: description,
6869
pubdate: pubdate,
6970
url: url,
70-
useCorsProxy: useCorsProxy
71+
useCorsProxy: useCorsProxy,
72+
hash: crypto.createHash("sha256").update(`${pubdate} :: ${title} :: ${url}`).digest("hex")
7173
});
7274
} else if (logFeedWarnings) {
7375
Log.warn("Can't parse feed item:");

0 commit comments

Comments
 (0)