diff --git a/defaultmodules/newsfeed/fullarticle.njk b/defaultmodules/newsfeed/fullarticle.njk deleted file mode 100644 index fbd6e437a1..0000000000 --- a/defaultmodules/newsfeed/fullarticle.njk +++ /dev/null @@ -1,3 +0,0 @@ -
- -
diff --git a/defaultmodules/newsfeed/newsfeed.css b/defaultmodules/newsfeed/newsfeed.css index 2c690a48e2..bdbcf1ca9b 100644 --- a/defaultmodules/newsfeed/newsfeed.css +++ b/defaultmodules/newsfeed/newsfeed.css @@ -1,12 +1,24 @@ -iframe.newsfeed-fullarticle { +.newsfeed-fullarticle-container { + position: fixed; width: 100vw; - - /* very large height value to allow scrolling */ - height: 3000px; + height: 100vh; top: 0; left: 0; + overflow-y: auto; + scrollbar-width: none; + z-index: 1000; + background: black; +} + +.newsfeed-fullarticle-container::-webkit-scrollbar { + display: none; +} + +iframe.newsfeed-fullarticle { + display: block; + width: 100%; + height: 5000px; border: none; - z-index: 1; } .region.bottom.bar.newsfeed-fullarticle { diff --git a/defaultmodules/newsfeed/newsfeed.js b/defaultmodules/newsfeed/newsfeed.js index cbe6e3264d..b24906962c 100644 --- a/defaultmodules/newsfeed/newsfeed.js +++ b/defaultmodules/newsfeed/newsfeed.js @@ -74,6 +74,10 @@ Module.register("newsfeed", { this.error = null; this.activeItem = 0; this.scrollPosition = 0; + this.articleIframe = null; + this.articleContainer = null; + this.articleFrameCheckPending = false; + this.articleUnavailable = false; this.registerFeeds(); @@ -97,15 +101,60 @@ Module.register("newsfeed", { } else if (notification === "NEWSFEED_ERROR") { this.error = this.translate(payload.error_type); this.scheduleUpdateInterval(); + } else if (notification === "ARTICLE_URL_STATUS") { + if (this.config.showFullArticle) { + this.articleFrameCheckPending = false; + this.articleUnavailable = !payload.canFrame; + if (!this.articleUnavailable) { + // Article can be framed — now shift the bottom bar to allow scrolling + document.getElementsByClassName("region bottom bar")[0].classList.add("newsfeed-fullarticle"); + } + this.updateDom(100); + if (this.articleUnavailable) { + // Briefly show the unavailable message, then return to normal newsfeed view + setTimeout(() => { + this.resetDescrOrFullArticleAndTimer(); + this.updateDom(500); + }, 3000); + } + } + } + }, + + //Override getDom to handle the full article case with error handling + getDom () { + if (this.config.showFullArticle) { + this.activeItemHash = this.newsItems[this.activeItem]?.hash; + const wrapper = document.createElement("div"); + if (this.articleFrameCheckPending) { + // Still waiting for the server-side framing check + wrapper.innerHTML = `
${this.translate("LOADING")}
`; + } else if (this.articleUnavailable) { + wrapper.innerHTML = `
${this.translate("NEWSFEED_ARTICLE_UNAVAILABLE")}
`; + } else { + const container = document.createElement("div"); + container.className = "newsfeed-fullarticle-container"; + container.scrollTop = this.scrollPosition; + const iframe = document.createElement("iframe"); + iframe.className = "newsfeed-fullarticle"; + // Always use the direct article URL — the CORS proxy is for server-side + // RSS feed fetching, not for browser iframes. + const item = this.newsItems[this.activeItem]; + iframe.src = item ? (typeof item.url === "string" ? item.url : item.url.href) : ""; + this.articleIframe = iframe; + this.articleContainer = container; + container.appendChild(iframe); + wrapper.appendChild(container); + } + return Promise.resolve(wrapper); } + return this._super(); }, //Override fetching of template name getTemplate () { if (this.config.feedUrl) { return "oldconfig.njk"; - } else if (this.config.showFullArticle) { - return "fullarticle.njk"; } return "newsfeed.njk"; }, @@ -116,13 +165,6 @@ Module.register("newsfeed", { this.activeItem = 0; } this.activeItemCount = this.newsItems.length; - // this.config.showFullArticle is a run-time configuration, triggered by optional notifications - if (this.config.showFullArticle) { - this.activeItemHash = this.newsItems[this.activeItem]?.hash; - return { - url: this.getActiveItemURL() - }; - } if (this.error) { this.activeItemHash = undefined; return { @@ -358,6 +400,10 @@ Module.register("newsfeed", { this.isShowingDescription = this.config.showDescription; this.config.showFullArticle = false; this.scrollPosition = 0; + this.articleIframe = null; + this.articleContainer = null; + this.articleFrameCheckPending = false; + this.articleUnavailable = false; // reset bottom bar alignment document.getElementsByClassName("region bottom bar")[0].classList.remove("newsfeed-fullarticle"); if (!this.timer) { @@ -386,23 +432,26 @@ Module.register("newsfeed", { Log.debug(`[newsfeed] going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`); this.updateDom(100); } - // if "more details" is received the first time: show article summary, on second time show full article else if (notification === "ARTICLE_MORE_DETAILS") { - // full article is already showing, so scrolling down if (this.config.showFullArticle === true) { + // iframe already showing — scroll down this.scrollPosition += this.config.scrollLength; - window.scrollTo(0, this.scrollPosition); - Log.debug("[newsfeed] scrolling down"); - Log.debug(`[newsfeed] ARTICLE_MORE_DETAILS, scroll position: ${this.config.scrollLength}`); - } else { + if (this.articleContainer) this.articleContainer.scrollTop = this.scrollPosition; + Log.debug(`[newsfeed] scrolling down, offset: ${this.scrollPosition}`); + } else if (this.isShowingDescription) { + // description visible — step up to full article this.showFullArticle(); + } else { + // only title visible — show description first + this.isShowingDescription = true; + Log.debug("[newsfeed] showing article description"); + this.updateDom(100); } } else if (notification === "ARTICLE_SCROLL_UP") { if (this.config.showFullArticle === true) { - this.scrollPosition -= this.config.scrollLength; - window.scrollTo(0, this.scrollPosition); - Log.debug("[newsfeed] scrolling up"); - Log.debug(`[newsfeed] ARTICLE_SCROLL_UP, scroll position: ${this.config.scrollLength}`); + this.scrollPosition = Math.max(0, this.scrollPosition - this.config.scrollLength); + if (this.articleContainer) this.articleContainer.scrollTop = this.scrollPosition; + Log.debug(`[newsfeed] scrolling up, offset: ${this.scrollPosition}`); } } else if (notification === "ARTICLE_LESS_DETAILS") { this.resetDescrOrFullArticleAndTimer(); @@ -416,26 +465,37 @@ Module.register("newsfeed", { this.showFullArticle(); } } else if (notification === "ARTICLE_INFO_REQUEST") { - this.sendNotification("ARTICLE_INFO_RESPONSE", { - title: this.newsItems[this.activeItem].title, - source: this.newsItems[this.activeItem].sourceTitle, - date: this.newsItems[this.activeItem].pubdate, - desc: this.newsItems[this.activeItem].description, - url: this.getActiveItemURL() - }); + const infoItem = this.newsItems[this.activeItem]; + if (infoItem) { + this.sendNotification("ARTICLE_INFO_RESPONSE", { + title: infoItem.title, + source: infoItem.sourceTitle, + date: infoItem.pubdate, + desc: infoItem.description, + url: typeof infoItem.url === "string" ? infoItem.url : infoItem.url.href + }); + } } }, showFullArticle () { - this.isShowingDescription = !this.isShowingDescription; - this.config.showFullArticle = !this.isShowingDescription; - // make bottom bar align to top to allow scrolling - if (this.config.showFullArticle === true) { - document.getElementsByClassName("region bottom bar")[0].classList.add("newsfeed-fullarticle"); + const item = this.newsItems[this.activeItem]; + const hasUrl = item && item.url && (typeof item.url === "string" ? item.url : item.url.href); + if (!hasUrl) { + Log.debug("[newsfeed] no article URL available, skipping full article view"); + return; } + this.isShowingDescription = false; + this.config.showFullArticle = true; + // Check server-side whether the article URL allows framing. + // The bottom bar CSS class is only added once we know the iframe will be shown. + this.articleFrameCheckPending = true; + this.articleUnavailable = false; + const rawUrl = typeof item.url === "string" ? item.url : item.url.href; + this.sendSocketNotification("CHECK_ARTICLE_URL", { url: rawUrl }); clearInterval(this.timer); this.timer = null; - Log.debug(`[newsfeed] showing ${this.isShowingDescription ? "article description" : "full article"}`); + Log.debug("[newsfeed] showing full article"); this.updateDom(100); } }); diff --git a/defaultmodules/newsfeed/node_helper.js b/defaultmodules/newsfeed/node_helper.js index 1101a72e4f..cede93f698 100644 --- a/defaultmodules/newsfeed/node_helper.js +++ b/defaultmodules/newsfeed/node_helper.js @@ -13,6 +13,28 @@ module.exports = NodeHelper.create({ socketNotificationReceived (notification, payload) { if (notification === "ADD_FEED") { this.createFetcher(payload.feed, payload.config); + } else if (notification === "CHECK_ARTICLE_URL") { + this.checkArticleUrl(payload.url); + } + }, + + /** + * Checks whether a URL can be displayed in an iframe by inspecting + * X-Frame-Options and Content-Security-Policy headers server-side. + * @param {string} url The article URL to check. + */ + async checkArticleUrl (url) { + try { + const response = await fetch(url, { method: "HEAD" }); + const xfo = response.headers.get("x-frame-options"); + const csp = response.headers.get("content-security-policy"); + // sameorigin also blocks since the article is on a different origin than MM + const blockedByXFO = xfo && ["deny", "sameorigin"].includes(xfo.toLowerCase().trim()); + const blockedByCSP = csp && (/frame-ancestors\s+['"]?none['"]?/).test(csp); + this.sendSocketNotification("ARTICLE_URL_STATUS", { url, canFrame: !blockedByXFO && !blockedByCSP }); + } catch { + // Network error or HEAD not supported — let the browser try the iframe anyway + this.sendSocketNotification("ARTICLE_URL_STATUS", { url, canFrame: true }); } }, diff --git a/tests/configs/modules/newsfeed/notifications.js b/tests/configs/modules/newsfeed/notifications.js new file mode 100644 index 0000000000..43bd0b1db1 --- /dev/null +++ b/tests/configs/modules/newsfeed/notifications.js @@ -0,0 +1,26 @@ +let config = { + address: "0.0.0.0", + ipWhitelist: [], + timeFormat: 12, + + modules: [ + { + module: "newsfeed", + position: "bottom_bar", + config: { + feeds: [ + { + title: "Rodrigo Ramirez Blog", + url: "http://localhost:8080/tests/mocks/newsfeed_test.xml" + } + ], + updateInterval: 3600 * 1000 // 1 hour - prevent auto-rotation during tests + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/e2e/modules/newsfeed_spec.js b/tests/e2e/modules/newsfeed_spec.js index 0d4c161e9a..b68b6ea5a6 100644 --- a/tests/e2e/modules/newsfeed_spec.js +++ b/tests/e2e/modules/newsfeed_spec.js @@ -70,6 +70,148 @@ const runTests = () => { }); }; +describe("Newsfeed module > Notifications", () => { + let page; + + afterAll(async () => { + await helpers.stopApplication(); + }); + + /** + * Helper: call notificationReceived on the newsfeed module directly. + * @param {object} p - playwright page + * @param {string} notification - notification name + * @param {object} payload - notification payload + * @returns {Promise} resolves when the notification has been dispatched + */ + const notify = (p, notification, payload = {}) => p.evaluate( + ({ n, pl }) => { + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + nf.notificationReceived(n, pl, nf); + }, + { n: notification, pl: payload } + ); + + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/newsfeed/notifications.js"); + await helpers.getDocument(); + page = helpers.getPage(); + await expect(page.locator(".newsfeed .newsfeed-title")).toBeVisible(); + }); + + it("ARTICLE_NEXT should show the next article", async () => { + const title1 = await page.locator(".newsfeed .newsfeed-title").textContent(); + await notify(page, "ARTICLE_NEXT"); + await expect(page.locator(".newsfeed .newsfeed-title")).not.toContainText(title1.trim()); + }); + + it("ARTICLE_PREVIOUS should return to the previous article", async () => { + // Start at article 0, go to article 1, then back + await page.evaluate(() => { + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + nf.activeItem = 0; + nf.resetDescrOrFullArticleAndTimer(); + nf.updateDom(0); + }); + await expect(page.locator(".newsfeed .newsfeed-title")).toContainText("QPanel"); + const title0 = await page.locator(".newsfeed .newsfeed-title").textContent(); + + await notify(page, "ARTICLE_NEXT"); + await expect(page.locator(".newsfeed .newsfeed-title")).not.toContainText(title0.trim()); + + await notify(page, "ARTICLE_PREVIOUS"); + await expect(page.locator(".newsfeed .newsfeed-title")).toContainText(title0.trim()); + }); + + it("ARTICLE_NEXT should wrap around from the last article to the first", async () => { + // Jump to the last article + await page.evaluate(() => { + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + nf.activeItem = nf.newsItems.length - 1; + nf.resetDescrOrFullArticleAndTimer(); + nf.updateDom(0); + }); + await expect(page.locator(".newsfeed .newsfeed-title")).toBeVisible(); + const titleLast = await page.locator(".newsfeed .newsfeed-title").textContent(); + + await notify(page, "ARTICLE_NEXT"); + await expect(page.locator(".newsfeed .newsfeed-title")).not.toContainText(titleLast.trim()); + + // activeItem should now be 0 + const activeItem = await page.evaluate(() => MM.getModules().find((m) => m.name === "newsfeed").activeItem); + expect(activeItem).toBe(0); + }); + + it("ARTICLE_PREVIOUS should wrap around from the first article to the last", async () => { + await page.evaluate(() => { + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + nf.activeItem = 0; + nf.resetDescrOrFullArticleAndTimer(); + }); + await notify(page, "ARTICLE_PREVIOUS"); + + const activeItem = await page.evaluate(() => { + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + return { activeItem: nf.activeItem, total: nf.newsItems.length }; + }); + expect(activeItem.activeItem).toBe(activeItem.total - 1); + }); + + it("ARTICLE_INFO_REQUEST should respond with title, source, date, desc and raw url", async () => { + await page.evaluate(() => { + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + nf.activeItem = 0; + nf.resetDescrOrFullArticleAndTimer(); + }); + + const info = await page.evaluate(() => new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error("ARTICLE_INFO_RESPONSE timeout")), 3000); + const origSend = MM.sendNotification.bind(MM); + MM.sendNotification = function (n, p, s) { + if (n === "ARTICLE_INFO_RESPONSE") { + clearTimeout(timer); + MM.sendNotification = origSend; + resolve(p); + } + return origSend(n, p, s); + }; + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + nf.notificationReceived("ARTICLE_INFO_REQUEST", {}, nf); + })); + + expect(info).toHaveProperty("title"); + expect(info).toHaveProperty("source"); + expect(info).toHaveProperty("date"); + expect(info).toHaveProperty("desc"); + expect(info).toHaveProperty("url"); + expect(info.title).toBe("QPanel 0.13.0"); + expect(info.source).toBe("Rodrigo Ramirez Blog"); + // URL must be the raw article URL, not a CORS proxy URL + expect(info.url).toMatch(/^https?:\/\//); + expect(info.url).not.toContain("localhost"); + }); + + it("ARTICLE_LESS_DETAILS should reset the full article view", async () => { + // Simulate full article view being active + await page.evaluate(() => { + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + nf.config.showFullArticle = true; + nf.articleFrameCheckPending = false; + nf.articleUnavailable = false; + }); + + await notify(page, "ARTICLE_LESS_DETAILS"); + + const state = await page.evaluate(() => { + const nf = MM.getModules().find((m) => m.name === "newsfeed"); + return { showFullArticle: nf.config.showFullArticle }; + }); + expect(state.showFullArticle).toBe(false); + // Normal newsfeed title should be visible again + await expect(page.locator(".newsfeed .newsfeed-title")).toBeVisible(); + }); +}); + describe("Newsfeed module", () => { afterAll(async () => { await helpers.stopApplication(); diff --git a/translations/af.json b/translations/af.json index 149e90a6be..8a138c24be 100644 --- a/translations/af.json +++ b/translations/af.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Gaan die logs na vir meer besonderhede.", "NEWSFEED_NO_ITEMS": "Geen nuus op die oomblik.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikel kan nie hier vertoon word nie.", "UPDATE_NOTIFICATION": "MagicMirror² update beskikbaar.", "UPDATE_NOTIFICATION_MODULE": "Update beskikbaar vir {MODULE_NAME} module.", diff --git a/translations/ar.json b/translations/ar.json index a0b7c09a7a..fd2bfb6b05 100644 --- a/translations/ar.json +++ b/translations/ar.json @@ -40,6 +40,7 @@ "MODULE_ERROR_UNSPECIFIED": "تحقق من السجلات لمزيد من التفاصيل.", "NEWSFEED_NO_ITEMS": "لا توجد أخبار في الوقت الحالي.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "لا يمكن عرض المقالة هنا.", "UPDATE_NOTIFICATION": "تحديث MagicMirror² متاح.", "UPDATE_NOTIFICATION_MODULE": "تحديث متاح لوحدة {MODULE_NAME}.", diff --git a/translations/bg.json b/translations/bg.json index 1f6b5eab55..018422cbad 100644 --- a/translations/bg.json +++ b/translations/bg.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Проверете логовете за повече подробности.", "NEWSFEED_NO_ITEMS": "Няма новини в момента.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Статията не може да бъде показана тук.", "UPDATE_NOTIFICATION": "Налична е актуализация за MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Налична е актуализация за модула „{MODULE_NAME}“.", diff --git a/translations/ca.json b/translations/ca.json index f9b5a0e63a..1832d2cb9f 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Consulta els registres per a més detalls.", "NEWSFEED_NO_ITEMS": "No hi ha notícies disponibles en aquest moment.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "L'article no es pot mostrar aquí.", "UPDATE_NOTIFICATION": "MagicMirror² actualizació disponible.", "UPDATE_NOTIFICATION_MODULE": "Disponible una actualizació per al mòdul {MODULE_NAME}.", diff --git a/translations/cs.json b/translations/cs.json index 931ea113a5..72034ace0f 100644 --- a/translations/cs.json +++ b/translations/cs.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Zkontrolujte protokoly pro více informací.", "NEWSFEED_NO_ITEMS": "Žádné zprávy.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Článek zde nelze zobrazit.", "UPDATE_NOTIFICATION": "Dostupná aktualizace pro MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Dostupná aktualizace pro modul {MODULE_NAME}.", diff --git a/translations/cv.json b/translations/cv.json index 6e4eafb3b6..22e2325ec7 100644 --- a/translations/cv.json +++ b/translations/cv.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Тӗп лог ҫӗнтерӗ.", "NEWSFEED_NO_ITEMS": "Пулас ҫӗнтер ҫук.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Article cannot be displayed here.", "UPDATE_NOTIFICATION": "MagicMirror² валли ҫӗнетӳ пур.", "UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME} модуль валли ҫӗнетӳ пур.", diff --git a/translations/cy.json b/translations/cy.json index 39395f3d09..d172aa2d7b 100644 --- a/translations/cy.json +++ b/translations/cy.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Gwiriwch y logiau am ragor o fanylion.", "NEWSFEED_NO_ITEMS": "Dim newyddion ar hyn o bryd.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Ni ellir dangos yr erthygl yma.", "UPDATE_NOTIFICATION": "MagicMirror² mwy diweddar yn barod.", "UPDATE_NOTIFICATION_MODULE": "Mae diweddaraiad ar gyfer y modiwl {MODULE_NAME}.", diff --git a/translations/da.json b/translations/da.json index edc650c2e9..6b56913955 100644 --- a/translations/da.json +++ b/translations/da.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Tjek logfiler for flere detaljer.", "NEWSFEED_NO_ITEMS": "Ingen nyheder i øjeblikket.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artiklen kan ikke vises her.", "UPDATE_NOTIFICATION": "MagicMirror² opdatering tilgængelig.", "UPDATE_NOTIFICATION_MODULE": "Opdatering tilgængelig for {MODULE_NAME} modulet.", diff --git a/translations/de.json b/translations/de.json index 69b17b1be4..af50e69c4e 100644 --- a/translations/de.json +++ b/translations/de.json @@ -43,6 +43,7 @@ "MODULE_ERROR_UNSPECIFIED": "Prüfe die Logdateien für weitere Details.", "NEWSFEED_NO_ITEMS": "Momentan keine Neuigkeiten.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikel kann hier nicht angezeigt werden.", "UPDATE_NOTIFICATION": "Aktualisierung für MagicMirror² verfügbar.", "UPDATE_NOTIFICATION_MODULE": "Aktualisierung für das Modul „{MODULE_NAME}“ verfügbar.", diff --git a/translations/el.json b/translations/el.json index 10146303f4..9cc161d55e 100644 --- a/translations/el.json +++ b/translations/el.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Ελέγξτε τα αρχεία καταγραφής για περισσότερες λεπτομέρειες.", "NEWSFEED_NO_ITEMS": "Δεν υπάρχουν ειδήσεις αυτή τη στιγμή.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Το άρθρο δεν μπορεί να εμφανιστεί εδώ.", "UPDATE_NOTIFICATION": "Διατίθεται ενημέρωση MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Διατίθεται ενημέρωση για το module {MODULE_NAME}.", diff --git a/translations/en.json b/translations/en.json index 9e95afa348..311d4973a2 100644 --- a/translations/en.json +++ b/translations/en.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Check logs for more details.", "NEWSFEED_NO_ITEMS": "No news at the moment.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Article cannot be displayed here.", "UPDATE_NOTIFICATION": "MagicMirror² update available.", "UPDATE_NOTIFICATION_MODULE": "Update available for {MODULE_NAME} module.", diff --git a/translations/eo.json b/translations/eo.json index 824282cd33..e1a9475fe3 100644 --- a/translations/eo.json +++ b/translations/eo.json @@ -43,6 +43,7 @@ "MODULE_ERROR_UNSPECIFIED": "Kontrolu la protokolajn dosierojn por pli da detaloj.", "NEWSFEED_NO_ITEMS": "Momente neniu novaĵoj.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikolo ne estas montrebla ĉi tie.", "UPDATE_NOTIFICATION": "Ĝisdatigo por MagicMirror² disponebla.", "UPDATE_NOTIFICATION_MODULE": "Ĝisdatigo por la modulo „{MODULE_NAME}“ disponebla.", diff --git a/translations/es.json b/translations/es.json index 30e06e7881..f157d35512 100644 --- a/translations/es.json +++ b/translations/es.json @@ -43,6 +43,7 @@ "MODULE_ERROR_UNSPECIFIED": "Por favor, consulte los registros para obtener más información.", "NEWSFEED_NO_ITEMS": "No hay noticias disponibles en este momento.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "El artículo no se puede mostrar aquí.", "UPDATE_NOTIFICATION": "MagicMirror² actualización disponible.", "UPDATE_NOTIFICATION_MODULE": "Disponible una actualización para el módulo {MODULE_NAME}.", diff --git a/translations/et.json b/translations/et.json index cf9e0099ed..e0777983d6 100644 --- a/translations/et.json +++ b/translations/et.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Lisateabe saamiseks kontrollige logifaile.", "NEWSFEED_NO_ITEMS": "Hetkel ei ole uudiseid.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artiklit ei saa siin kuvada.", "UPDATE_NOTIFICATION": "MagicMirror²'le on uuendus saadaval.", "UPDATE_NOTIFICATION_MODULE": "Uuendus saadaval {MODULE_NAME} moodulile.", diff --git a/translations/fi.json b/translations/fi.json index c201fbb8e0..b6e2d303c7 100644 --- a/translations/fi.json +++ b/translations/fi.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Tarkista lokitiedostot saadaksesi lisätietoja.", "NEWSFEED_NO_ITEMS": "Ei uutisia tällä hetkellä.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikkelia ei voi näyttää täällä.", "UPDATE_NOTIFICATION": "MagicMirror² päivitys saatavilla.", "UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille {MODULE_NAME}.", diff --git a/translations/fr.json b/translations/fr.json index e4c05e7985..47c9369b78 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -43,6 +43,7 @@ "MODULE_ERROR_UNSPECIFIED": "Consultez les journaux pour plus de détails.", "NEWSFEED_NO_ITEMS": "Aucune nouvelle pour le moment.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "L'article ne peut pas être affiché ici.", "UPDATE_NOTIFICATION": "Une mise à jour de MagicMirror² est disponible", "UPDATE_NOTIFICATION_MODULE": "Une mise à jour est disponible pour le module {MODULE_NAME}.", diff --git a/translations/fy.json b/translations/fy.json index 939002669f..01d0133bed 100644 --- a/translations/fy.json +++ b/translations/fy.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Sjoch de logs foar mear ynformaasje.", "NEWSFEED_NO_ITEMS": "Op it stuit gjin nijsberjochten.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikel kin hjir net werjûn wurde.", "UPDATE_NOTIFICATION": "Der is in update beskikber foar MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Der is in update beskikber foar it {MODULE_NAME} module.", diff --git a/translations/gl.json b/translations/gl.json index 7d410971da..217029b537 100644 --- a/translations/gl.json +++ b/translations/gl.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Verifique os rexistros para obter máis información.", "NEWSFEED_NO_ITEMS": "Non hai novas no momento.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "O artigo non se pode mostrar aquí.", "UPDATE_NOTIFICATION": "Actualización dispoñible para MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Actualización dispoñible para o módulo {MODULE_NAME}.", diff --git a/translations/gu.json b/translations/gu.json index 32ea8ce350..bbd5fb5a5a 100644 --- a/translations/gu.json +++ b/translations/gu.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "વધુ વિગતો માટે લોગ તપાસો.", "NEWSFEED_NO_ITEMS": "હાલમાં કોઈ સમાચાર નથી.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "લેખ અહીં પ્રદર્શિત કરી શકાતો નથી.", "UPDATE_NOTIFICATION": "MagicMirror² અપડેટ ઉપલબ્ધ છે.", "UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME} મોડ્યુલ માટે અપડેટ ઉપલબ્ધ છે.", diff --git a/translations/he.json b/translations/he.json index 998504c2ed..45c440ea26 100644 --- a/translations/he.json +++ b/translations/he.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "בדוק את היומנים לפרטים נוספים.", "NEWSFEED_NO_ITEMS": "אין חדשות כרגע.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "לא ניתן להציג את המאמר כאן.", "UPDATE_NOTIFICATION": "עדכון זמין ל-MagicMirror²", "UPDATE_NOTIFICATION_MODULE": "עדכון זמין ב-{MODULE_NAME} מודול", diff --git a/translations/hi.json b/translations/hi.json index 890b2ebd3b..a488e397b5 100644 --- a/translations/hi.json +++ b/translations/hi.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "अधिक जानकारी के लिए लॉग जांचें।", "NEWSFEED_NO_ITEMS": "इस समय कोई समाचार नहीं।", + "NEWSFEED_ARTICLE_UNAVAILABLE": "लेख यहाँ प्रदर्शित नहीं किया जा सकता।", "UPDATE_NOTIFICATION": "MagicMirror² अपडेट उपलब्ध।", "UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME} मॉड्यूल के लिए उपलब्ध अद्यतन।", diff --git a/translations/hr.json b/translations/hr.json index 18c01e24d5..93d59c967e 100644 --- a/translations/hr.json +++ b/translations/hr.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Provjerite dnevnike za više informacija.", "NEWSFEED_NO_ITEMS": "Trenutno nema vijesti.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Članak se ne može prikazati ovdje.", "UPDATE_NOTIFICATION": "Dostupna je aktualizacija MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Dostupna je aktualizacija modula {MODULE_NAME}.", diff --git a/translations/hu.json b/translations/hu.json index db96e63051..e8b6b12028 100644 --- a/translations/hu.json +++ b/translations/hu.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Ellenőrizze a naplókat további részletekért.", "NEWSFEED_NO_ITEMS": "Jelenleg nincsenek hírek.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "A cikk itt nem jeleníthető meg.", "UPDATE_NOTIFICATION": "MagicMirror²-hoz frissítés érhető el.", "UPDATE_NOTIFICATION_MODULE": "A {MODULE_NAME} modulhoz frissítés érhető el.", diff --git a/translations/id.json b/translations/id.json index c5b4e6a4c3..738bd940da 100644 --- a/translations/id.json +++ b/translations/id.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Silakan periksa log untuk informasi lebih lanjut.", "NEWSFEED_NO_ITEMS": "Saat ini tidak ada berita.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikel tidak dapat ditampilkan di sini.", "UPDATE_NOTIFICATION": "Memperbarui MagicMirror² tersedia.", "UPDATE_NOTIFICATION_MODULE": "Memperbarui tersedia untuk modul {MODULE_NAME}.", diff --git a/translations/is.json b/translations/is.json index 3ca35da4c4..e21d6efb73 100644 --- a/translations/is.json +++ b/translations/is.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Vinsamlegast athugaðu skráningu fyrir frekari upplýsingar.", "NEWSFEED_NO_ITEMS": "Engar fréttir í boði núna.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Grein er ekki hægt að sýna hér.", "UPDATE_NOTIFICATION": "MagicMirror² uppfærsla í boði.", "UPDATE_NOTIFICATION_MODULE": "Uppfærsla í boði fyrir {MODULE_NAME} module.", diff --git a/translations/it.json b/translations/it.json index d8ca1f990f..7c4591e4bf 100644 --- a/translations/it.json +++ b/translations/it.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Si prega di controllare i log per ulteriori dettagli.", "NEWSFEED_NO_ITEMS": "Al momento non ci sono notizie.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "L'articolo non può essere visualizzato qui.", "UPDATE_NOTIFICATION": "E' disponibile un aggiornamento di MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "E' disponibile un aggiornamento del modulo {MODULE_NAME}.", diff --git a/translations/ja.json b/translations/ja.json index 2ec19581c9..22052f014b 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "詳細はログを確認してください。", "NEWSFEED_NO_ITEMS": "現在ニュースはありません。", + "NEWSFEED_ARTICLE_UNAVAILABLE": "この記事はここでは表示できません。", "UPDATE_NOTIFICATION": "MagicMirror² のアップデートが利用可能です。", "UPDATE_NOTIFICATION_MODULE": "モジュール {MODULE_NAME} のアップデートが利用可能です。", diff --git a/translations/ko.json b/translations/ko.json index c5d223e817..9ee81b2edb 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "상세 내용은 로그를 확인하세요.", "NEWSFEED_NO_ITEMS": "현재 뉴스가 없습니다.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "이 기사는 여기에 표시할 수 없습니다.", "UPDATE_NOTIFICATION": "새로운 MagicMirror² 업데이트가 있습니다.", "UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME} 모듈에서 사용 가능한 업데이트 입니다.", diff --git a/translations/lt.json b/translations/lt.json index 75ed4d8979..cfc5353b02 100644 --- a/translations/lt.json +++ b/translations/lt.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Patikrinkite žurnalus, kad gautumėte daugiau informacijos.", "NEWSFEED_NO_ITEMS": "Šiuo metu naujienų nėra.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Straipsnis čia negali būti rodomas.", "UPDATE_NOTIFICATION": "Galimas MagicMirror² naujinimas.", "UPDATE_NOTIFICATION_MODULE": "Galimas {MODULE_NAME} naujinimas.", diff --git a/translations/ms-my.json b/translations/ms-my.json index 54e0bffc52..e93dd8cdf1 100644 --- a/translations/ms-my.json +++ b/translations/ms-my.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Sila semak log untuk maklumat lanjut.", "NEWSFEED_NO_ITEMS": "Tiada berita buat masa ini.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikel tidak dapat dipaparkan di sini.", "UPDATE_NOTIFICATION": "MagicMirror² mempunyai update terkini.", "UPDATE_NOTIFICATION_MODULE": "Modul {MODULE_NAME} mempunyai update terkini.", diff --git a/translations/nb.json b/translations/nb.json index 3dd5f20983..d459ff90ba 100644 --- a/translations/nb.json +++ b/translations/nb.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Vennligst sjekk loggene for mer informasjon.", "NEWSFEED_NO_ITEMS": "Ingen nyheter tilgjengelig for øyeblikket.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikkelen kan ikke vises her.", "UPDATE_NOTIFICATION": "MagicMirror²-oppdatering er tilgjengelig.", "UPDATE_NOTIFICATION_MODULE": "Oppdatering tilgjengelig for modulen {MODULE_NAME}.", diff --git a/translations/nl.json b/translations/nl.json index e4f8a77585..6102c1de54 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Bekijk de logs voor meer informatie.", "NEWSFEED_NO_ITEMS": "Geen nieuws op dit moment.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikel kan hier niet worden weergegeven.", "UPDATE_NOTIFICATION": "MagicMirror² update beschikbaar.", "UPDATE_NOTIFICATION_MODULE": "Update beschikbaar voor {MODULE_NAME} module.", diff --git a/translations/nn.json b/translations/nn.json index 833f3c3df8..8706cc198b 100644 --- a/translations/nn.json +++ b/translations/nn.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Vennligst sjekk loggfilene for meir informasjon.", "NEWSFEED_NO_ITEMS": "Ingen nyhende tilgjengeleg no.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikkelen kan ikkje visast her.", "UPDATE_NOTIFICATION": "MagicMirror² oppdatering er tilgjengeleg.", "UPDATE_NOTIFICATION_MODULE": "Oppdatering tilgjengeleg for modulen {MODULE_NAME}.", diff --git a/translations/pl.json b/translations/pl.json index 545c8fe9e5..a74143b62c 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Sprawdź logi, aby uzyskać więcej informacji.", "NEWSFEED_NO_ITEMS": "Brak wiadomości w tej chwili.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artykuł nie może być wyświetlony tutaj.", "UPDATE_NOTIFICATION": "Dostępna jest aktualizacja MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Dostępna jest aktualizacja modułu {MODULE_NAME}.", diff --git a/translations/ps.json b/translations/ps.json index 701c30e82a..d9390dcc0c 100644 --- a/translations/ps.json +++ b/translations/ps.json @@ -34,5 +34,8 @@ "UPDATE_NOTIFICATION": "د MagicMirror² نوې نسخه سته ", "UPDATE_NOTIFICATION_MODULE": "د {MODULE_NAME} نوی نسخه سته", "UPDATE_INFO_SINGLE": "اوسنی برخه {COMMIT_COUNT} د {BRANCH_NAME} څخه وروسته پاته ده", - "UPDATE_INFO_MULTIPLE": "اوسنی برخه {COMMIT_COUNT} د {BRANCH_NAME} څخه وروسته پاته ده" + "UPDATE_INFO_MULTIPLE": "اوسنی برخه {COMMIT_COUNT} د {BRANCH_NAME} څخه وروسته پاته ده", + + "NEWSFEED_NO_ITEMS": "مقاله شتون نلري.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "مقاله دلته نه شي ښودل کیدی." } diff --git a/translations/pt-br.json b/translations/pt-br.json index 6c59fec9ab..4fdf6044e7 100644 --- a/translations/pt-br.json +++ b/translations/pt-br.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Verifique os logs para mais detalhes.", "NEWSFEED_NO_ITEMS": "Atualmente não há notícias.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "O artigo não pode ser exibido aqui.", "UPDATE_NOTIFICATION": "Nova atualização para MagicMirror² disponível.", "UPDATE_NOTIFICATION_MODULE": "Atualização para o módulo {MODULE_NAME} disponível.", diff --git a/translations/pt.json b/translations/pt.json index 3c1f26bde4..44770c7133 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -43,6 +43,7 @@ "MODULE_ERROR_UNSPECIFIED": "Consulta os registos para mais detalhes.", "NEWSFEED_NO_ITEMS": "Sem notícias de momento.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "O artigo não pode ser apresentado aqui.", "UPDATE_NOTIFICATION": "Está disponível uma atualização do MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Atualização disponível para o módulo {MODULE_NAME}.", diff --git a/translations/ro.json b/translations/ro.json index 4d0422f1f2..5119fecefb 100644 --- a/translations/ro.json +++ b/translations/ro.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Verificați jurnalele pentru mai multe detalii.", "NEWSFEED_NO_ITEMS": "Nu există știri în acest moment.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Articolul nu poate fi afișat aici.", "UPDATE_NOTIFICATION": "Un update este disponibil pentru MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Un update este disponibil pentru modulul {MODULE_NAME}.", diff --git a/translations/ru.json b/translations/ru.json index 6620f1bcde..bf5c969a04 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Пожалуйста, проверьте логи для получения дополнительной информации.", "NEWSFEED_NO_ITEMS": "В данный момент нет новостей.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Статья не может быть отображена здесь.", "UPDATE_NOTIFICATION": "Есть обновление для MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Есть обновление для {MODULE_NAME} модуля.", diff --git a/translations/sk.json b/translations/sk.json index 2407126eb8..a420a45bbf 100644 --- a/translations/sk.json +++ b/translations/sk.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Skontrolujte protokoly pre viac informácií.", "NEWSFEED_NO_ITEMS": "Momentálne žiadne správy.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Článok sa tu nedá zobraziť.", "UPDATE_NOTIFICATION": "Dostupná aktualizácia pre MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Dostupná aktualizácia pre modul {MODULE_NAME}.", diff --git a/translations/sv.json b/translations/sv.json index 0add5c4360..a05c1b7275 100644 --- a/translations/sv.json +++ b/translations/sv.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Vänligen kontrollera loggarna för mer information.", "NEWSFEED_NO_ITEMS": "Inga nyheter för tillfället.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Artikeln kan inte visas här.", "UPDATE_NOTIFICATION": "MagicMirror² uppdatering finns tillgänglig.", "UPDATE_NOTIFICATION_MODULE": "Uppdatering finns tillgänglig av {MODULE_NAME} modulen.", diff --git a/translations/th.json b/translations/th.json index dfa120f33f..1a2bfd40bb 100644 --- a/translations/th.json +++ b/translations/th.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "ตรวจสอบบันทึกสำหรับรายละเอียดเพิ่มเติม", "NEWSFEED_NO_ITEMS": "ไม่มีข่าวในขณะนี้", + "NEWSFEED_ARTICLE_UNAVAILABLE": "ไม่สามารถแสดงบทความที่นี่ได้", "UPDATE_NOTIFICATION": "MagicMirror² มีการอัปเดต", "UPDATE_NOTIFICATION_MODULE": "มีการอัปเดตสำหรับโมดูล {MODULE_NAME}", diff --git a/translations/tlh.json b/translations/tlh.json index b7a70a4368..295d40d411 100644 --- a/translations/tlh.json +++ b/translations/tlh.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "logmeyDaq yImev.", "NEWSFEED_NO_ITEMS": "DaHghachmey ghobe' yImev.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "QIngheb cha' tu'be'lu'.", "UPDATE_NOTIFICATION": " De'chu' MagicMirror² lI'laH.", "UPDATE_NOTIFICATION_MODULE": "bobcho' {MODULE_NAME} lI'laH De'chu.", diff --git a/translations/tr.json b/translations/tr.json index 6e0d3ad249..6688addabe 100644 --- a/translations/tr.json +++ b/translations/tr.json @@ -41,6 +41,7 @@ "MODULE_ERROR_UNSPECIFIED": "Daha fazla ayrıntı için günlükleri kontrol edin.", "NEWSFEED_NO_ITEMS": "Şu anda haber yok.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Makale burada görüntülenemiyor.", "UPDATE_NOTIFICATION": "MagicMirror² güncellemesi mevcut.", "UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME} modulü için güncelleme mevcut.", diff --git a/translations/uk.json b/translations/uk.json index ffc308226a..1aad1ba6f9 100644 --- a/translations/uk.json +++ b/translations/uk.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "Перевірте журнали для отримання додаткової інформації.", "NEWSFEED_NO_ITEMS": "Немає новин на даний момент.", + "NEWSFEED_ARTICLE_UNAVAILABLE": "Статтю неможливо відобразити тут.", "UPDATE_NOTIFICATION": "Є оновлення для MagicMirror².", "UPDATE_NOTIFICATION_MODULE": "Є оновлення для модуля {MODULE_NAME}.", diff --git a/translations/zh-cn.json b/translations/zh-cn.json index 7e1cf7ca65..146a8a0881 100644 --- a/translations/zh-cn.json +++ b/translations/zh-cn.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "请查看日志以获取更多详细信息。", "NEWSFEED_NO_ITEMS": "目前没有新闻。", + "NEWSFEED_ARTICLE_UNAVAILABLE": "文章无法在此处显示。", "UPDATE_NOTIFICATION": "MagicMirror²有新的版本。", "UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME}模块可更新。", diff --git a/translations/zh-tw.json b/translations/zh-tw.json index 13c4edab90..1c21632bba 100644 --- a/translations/zh-tw.json +++ b/translations/zh-tw.json @@ -42,6 +42,7 @@ "MODULE_ERROR_UNSPECIFIED": "查看日誌以了解詳情。", "NEWSFEED_NO_ITEMS": "目前沒有新聞。", + "NEWSFEED_ARTICLE_UNAVAILABLE": "文章無法在此處顯示。", "UPDATE_NOTIFICATION": "MagicMirror² 有可用更新。", "UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME} 模組有可用更新。",