diff --git a/commafeed-client/src/components/AnnouncementDialog.tsx b/commafeed-client/src/components/AnnouncementDialog.tsx
new file mode 100644
index 00000000..85a71b88
--- /dev/null
+++ b/commafeed-client/src/components/AnnouncementDialog.tsx
@@ -0,0 +1,36 @@
+import { Trans } from "@lingui/macro"
+import { Box, Dialog, Text } from "@mantine/core"
+import { useAppSelector } from "app/store"
+import { Content } from "components/content/Content"
+import { useAsync } from "react-async-hook"
+import useLocalStorage from "use-local-storage"
+
+const sha256Hex = async (input: string | undefined) => {
+ const data = new TextEncoder().encode(input)
+ const buffer = await crypto.subtle.digest("SHA-256", data)
+ const array = Array.from(new Uint8Array(buffer))
+ return array.map(b => b.toString(16).padStart(2, "0")).join("")
+}
+
+export function AnnouncementDialog() {
+ const announcement = useAppSelector(state => state.server.serverInfos?.announcement)
+ const announcementHash = useAsync(sha256Hex, [announcement]).result
+ const [localStorageHash, setLocalStorageHash] = useLocalStorage("announcement-hash", "no-hash")
+
+ const opened = !!announcementHash && announcementHash !== localStorageHash
+ const onClosed = () => setLocalStorageHash(announcementHash)
+
+ if (!announcement) return null
+ return (
+
+ )
+}
diff --git a/commafeed-client/src/locales/ar/messages.po b/commafeed-client/src/locales/ar/messages.po
index 2c332c4a..0ef9c608 100644
--- a/commafeed-client/src/locales/ar/messages.po
+++ b/commafeed-client/src/locales/ar/messages.po
@@ -87,6 +87,10 @@ msgstr "ملف opml هو ملف XML يحتوي على عناوين URL للتغ
msgid "Analyze feed"
msgstr "تحليل التغذية"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "مفتاح API"
diff --git a/commafeed-client/src/locales/ca/messages.po b/commafeed-client/src/locales/ca/messages.po
index b7a4db58..9aeb592f 100644
--- a/commafeed-client/src/locales/ca/messages.po
+++ b/commafeed-client/src/locales/ca/messages.po
@@ -87,6 +87,10 @@ msgstr "Un fitxer opml és un fitxer XML que conté URL i categories de canals.
msgid "Analyze feed"
msgstr "Analitzar el feed"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "clau API"
diff --git a/commafeed-client/src/locales/cs/messages.po b/commafeed-client/src/locales/cs/messages.po
index 562a3983..a7b799f9 100644
--- a/commafeed-client/src/locales/cs/messages.po
+++ b/commafeed-client/src/locales/cs/messages.po
@@ -87,6 +87,10 @@ msgstr "Soubor opml je soubor XML obsahující adresy URL a kategorie zdrojů. "
msgid "Analyze feed"
msgstr "Analyzujte krmivo"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "Klíč API"
diff --git a/commafeed-client/src/locales/cy/messages.po b/commafeed-client/src/locales/cy/messages.po
index 38f06365..9acb66d7 100644
--- a/commafeed-client/src/locales/cy/messages.po
+++ b/commafeed-client/src/locales/cy/messages.po
@@ -87,6 +87,10 @@ msgstr "Mae ffeil opml yn ffeil XML sy'n cynnwys URLs porthiant a chategorïau.
msgid "Analyze feed"
msgstr "Dadansoddi porthiant"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "Allwedd API"
diff --git a/commafeed-client/src/locales/da/messages.po b/commafeed-client/src/locales/da/messages.po
index 44485207..972f1af9 100644
--- a/commafeed-client/src/locales/da/messages.po
+++ b/commafeed-client/src/locales/da/messages.po
@@ -87,6 +87,10 @@ msgstr "En opml-fil er en XML-fil, der indeholder feed-URL'er og kategorier. "
msgid "Analyze feed"
msgstr "Analyser foder"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API-nøgle"
diff --git a/commafeed-client/src/locales/de/messages.po b/commafeed-client/src/locales/de/messages.po
index 36507ba8..f251089f 100644
--- a/commafeed-client/src/locales/de/messages.po
+++ b/commafeed-client/src/locales/de/messages.po
@@ -87,6 +87,10 @@ msgstr "Eine opml-Datei ist eine XML-Datei, die Feed-URLs und Kategorien enthäl
msgid "Analyze feed"
msgstr "Feed analysieren"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API-Schlüssel"
diff --git a/commafeed-client/src/locales/en/messages.po b/commafeed-client/src/locales/en/messages.po
index a68b40f6..db596ee7 100644
--- a/commafeed-client/src/locales/en/messages.po
+++ b/commafeed-client/src/locales/en/messages.po
@@ -87,6 +87,10 @@ msgstr "An opml file is an XML file containing feed URLs and categories. You can
msgid "Analyze feed"
msgstr "Analyze feed"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr "Announcement"
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API key"
diff --git a/commafeed-client/src/locales/es/messages.po b/commafeed-client/src/locales/es/messages.po
index ca4a71c2..bead5a57 100644
--- a/commafeed-client/src/locales/es/messages.po
+++ b/commafeed-client/src/locales/es/messages.po
@@ -87,6 +87,10 @@ msgstr "Un archivo opml es un archivo XML que contiene categorías y direcciones
msgid "Analyze feed"
msgstr "Analizar alimentación"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "clave API"
diff --git a/commafeed-client/src/locales/fa/messages.po b/commafeed-client/src/locales/fa/messages.po
index c62fad1f..867806b2 100644
--- a/commafeed-client/src/locales/fa/messages.po
+++ b/commafeed-client/src/locales/fa/messages.po
@@ -87,6 +87,10 @@ msgstr "یک فایل opml یک فایل XML است که حاوی آدرسه
msgid "Analyze feed"
msgstr "خوراک را تجزیه و تحلیل کنید"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "کلید API"
diff --git a/commafeed-client/src/locales/fi/messages.po b/commafeed-client/src/locales/fi/messages.po
index c228d28b..ce042693 100644
--- a/commafeed-client/src/locales/fi/messages.po
+++ b/commafeed-client/src/locales/fi/messages.po
@@ -87,6 +87,10 @@ msgstr "Opml-tiedosto on XML-tiedosto, joka sisältää syötteen URL-osoitteet
msgid "Analyze feed"
msgstr "Analysoi syöte"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API-avain"
diff --git a/commafeed-client/src/locales/fr/messages.po b/commafeed-client/src/locales/fr/messages.po
index d8da712f..5d8f83fc 100644
--- a/commafeed-client/src/locales/fr/messages.po
+++ b/commafeed-client/src/locales/fr/messages.po
@@ -87,6 +87,10 @@ msgstr "Un fichier OPML est un fichier XML contenant des URL de flux et des cat
msgid "Analyze feed"
msgstr "Analyser le flux"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "Clé API"
diff --git a/commafeed-client/src/locales/gl/messages.po b/commafeed-client/src/locales/gl/messages.po
index 35dd6498..0630e27f 100644
--- a/commafeed-client/src/locales/gl/messages.po
+++ b/commafeed-client/src/locales/gl/messages.po
@@ -87,6 +87,10 @@ msgstr "Un ficheiro opml é un ficheiro XML que contén URL e categorías de fon
msgid "Analyze feed"
msgstr "Analizar feed"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "chave API"
diff --git a/commafeed-client/src/locales/hu/messages.po b/commafeed-client/src/locales/hu/messages.po
index a4b6916f..a4aee6fa 100644
--- a/commafeed-client/src/locales/hu/messages.po
+++ b/commafeed-client/src/locales/hu/messages.po
@@ -87,6 +87,10 @@ msgstr "Az opml-fájl olyan XML-fájl, amely feed URL-címeket és kategóriáka
msgid "Analyze feed"
msgstr "Hírcsatorna elemzése"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API kulcs"
diff --git a/commafeed-client/src/locales/id/messages.po b/commafeed-client/src/locales/id/messages.po
index 68be40da..8394857b 100644
--- a/commafeed-client/src/locales/id/messages.po
+++ b/commafeed-client/src/locales/id/messages.po
@@ -87,6 +87,10 @@ msgstr "File opml adalah file XML yang berisi URL dan kategori feed. "
msgid "Analyze feed"
msgstr "Analisis umpan"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "kunci API"
diff --git a/commafeed-client/src/locales/it/messages.po b/commafeed-client/src/locales/it/messages.po
index 924f1b8d..51900551 100644
--- a/commafeed-client/src/locales/it/messages.po
+++ b/commafeed-client/src/locales/it/messages.po
@@ -87,6 +87,10 @@ msgstr "Un file opml è un file XML contenente URL e categorie di feed. "
msgid "Analyze feed"
msgstr "Analizza feed"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "Chiave API"
diff --git a/commafeed-client/src/locales/ja/messages.po b/commafeed-client/src/locales/ja/messages.po
index b91e3bc9..f42fe8b9 100644
--- a/commafeed-client/src/locales/ja/messages.po
+++ b/commafeed-client/src/locales/ja/messages.po
@@ -87,6 +87,10 @@ msgstr "opml ファイルは、フィードの URL とカテゴリを含む XML
msgid "Analyze feed"
msgstr "フィードを分析する"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "APIキー"
diff --git a/commafeed-client/src/locales/ko/messages.po b/commafeed-client/src/locales/ko/messages.po
index fbc91653..9fcd34d2 100644
--- a/commafeed-client/src/locales/ko/messages.po
+++ b/commafeed-client/src/locales/ko/messages.po
@@ -87,6 +87,10 @@ msgstr "opml 파일은 피드 URL과 카테고리를 포함하는 XML 파일입
msgid "Analyze feed"
msgstr "피드 분석"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API 키"
diff --git a/commafeed-client/src/locales/ms/messages.po b/commafeed-client/src/locales/ms/messages.po
index 79055fac..4a8a85e8 100644
--- a/commafeed-client/src/locales/ms/messages.po
+++ b/commafeed-client/src/locales/ms/messages.po
@@ -87,6 +87,10 @@ msgstr "Fail opml ialah fail XML yang mengandungi URL suapan dan kategori. "
msgid "Analyze feed"
msgstr "Menganalisis suapan"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "Kunci API"
diff --git a/commafeed-client/src/locales/nb/messages.po b/commafeed-client/src/locales/nb/messages.po
index 73b99859..552d0763 100644
--- a/commafeed-client/src/locales/nb/messages.po
+++ b/commafeed-client/src/locales/nb/messages.po
@@ -87,6 +87,10 @@ msgstr "En opml-fil er en XML-fil som inneholder feed-URLer og kategorier. "
msgid "Analyze feed"
msgstr "Analyser feed"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API-nøkkel"
diff --git a/commafeed-client/src/locales/nl/messages.po b/commafeed-client/src/locales/nl/messages.po
index ee3db62d..34e35323 100644
--- a/commafeed-client/src/locales/nl/messages.po
+++ b/commafeed-client/src/locales/nl/messages.po
@@ -87,6 +87,10 @@ msgstr "Een opml-bestand is een XML-bestand met feed-URL's en categorieën. "
msgid "Analyze feed"
msgstr "Analyseer feed"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API-sleutel"
diff --git a/commafeed-client/src/locales/nn/messages.po b/commafeed-client/src/locales/nn/messages.po
index 7f16e5c8..c534b780 100644
--- a/commafeed-client/src/locales/nn/messages.po
+++ b/commafeed-client/src/locales/nn/messages.po
@@ -87,6 +87,10 @@ msgstr "En opml-fil er en XML-fil som inneholder feed-URLer og kategorier. "
msgid "Analyze feed"
msgstr "Analyser feed"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API-nøkkel"
diff --git a/commafeed-client/src/locales/pl/messages.po b/commafeed-client/src/locales/pl/messages.po
index bdc72d70..d985d6cf 100644
--- a/commafeed-client/src/locales/pl/messages.po
+++ b/commafeed-client/src/locales/pl/messages.po
@@ -87,6 +87,10 @@ msgstr "Plik opml to plik XML zawierający adresy URL i kategorie kanałów. "
msgid "Analyze feed"
msgstr "Analizuj kanał"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "klucz API"
diff --git a/commafeed-client/src/locales/pt/messages.po b/commafeed-client/src/locales/pt/messages.po
index 15b2ae9c..9eba4f6d 100644
--- a/commafeed-client/src/locales/pt/messages.po
+++ b/commafeed-client/src/locales/pt/messages.po
@@ -87,6 +87,10 @@ msgstr "Um arquivo opml é um arquivo XML contendo URLs e categorias de feed. "
msgid "Analyze feed"
msgstr "Analisar feed"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "chave de API"
diff --git a/commafeed-client/src/locales/ru/messages.po b/commafeed-client/src/locales/ru/messages.po
index 31b256a2..eaa688bd 100644
--- a/commafeed-client/src/locales/ru/messages.po
+++ b/commafeed-client/src/locales/ru/messages.po
@@ -87,6 +87,10 @@ msgstr "OPML-файл — это XML-файл, содержащий URL-адре
msgid "Analyze feed"
msgstr "Анализ канала"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "ключ API"
diff --git a/commafeed-client/src/locales/sk/messages.po b/commafeed-client/src/locales/sk/messages.po
index baac003f..1edf8ad2 100644
--- a/commafeed-client/src/locales/sk/messages.po
+++ b/commafeed-client/src/locales/sk/messages.po
@@ -87,6 +87,10 @@ msgstr "Súbor opml je súbor XML obsahujúci adresy URL kanálov a kategórie.
msgid "Analyze feed"
msgstr "Analyzujte krmivo"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "Kľúč API"
diff --git a/commafeed-client/src/locales/sv/messages.po b/commafeed-client/src/locales/sv/messages.po
index 79df40b6..c9862ca9 100644
--- a/commafeed-client/src/locales/sv/messages.po
+++ b/commafeed-client/src/locales/sv/messages.po
@@ -87,6 +87,10 @@ msgstr "En opml-fil är en XML-fil som innehåller feed-URL:er och kategorier. "
msgid "Analyze feed"
msgstr "Analysera foder"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API-nyckel"
diff --git a/commafeed-client/src/locales/tr/messages.po b/commafeed-client/src/locales/tr/messages.po
index 5f424fd8..215b1983 100644
--- a/commafeed-client/src/locales/tr/messages.po
+++ b/commafeed-client/src/locales/tr/messages.po
@@ -87,6 +87,10 @@ msgstr "Bir opml dosyası, besleme URL'lerini ve kategorilerini içeren bir XML
msgid "Analyze feed"
msgstr "Feed'i analiz et"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API anahtarı"
diff --git a/commafeed-client/src/locales/zh/messages.po b/commafeed-client/src/locales/zh/messages.po
index dc7b1dd4..d24728ec 100644
--- a/commafeed-client/src/locales/zh/messages.po
+++ b/commafeed-client/src/locales/zh/messages.po
@@ -87,6 +87,10 @@ msgstr "opml 文件是包含提要 URL 和类别的 XML 文件。"
msgid "Analyze feed"
msgstr "分析饲料"
+#: src/components/AnnouncementDialog.tsx
+msgid "Announcement"
+msgstr ""
+
#: src/components/settings/ProfileSettings.tsx
msgid "API key"
msgstr "API 密钥"
diff --git a/commafeed-client/src/pages/app/Layout.tsx b/commafeed-client/src/pages/app/Layout.tsx
index c781103b..06435a01 100644
--- a/commafeed-client/src/pages/app/Layout.tsx
+++ b/commafeed-client/src/pages/app/Layout.tsx
@@ -18,6 +18,7 @@ import { redirectToAdd, redirectToRootCategory } from "app/slices/redirect"
import { reloadTree, setMobileMenuOpen, setSidebarWidth } from "app/slices/tree"
import { reloadProfile, reloadSettings, reloadTags } from "app/slices/user"
import { useAppDispatch, useAppSelector } from "app/store"
+import { AnnouncementDialog } from "components/AnnouncementDialog"
import { Loader } from "components/Loader"
import { Logo } from "components/Logo"
import { OnDesktop } from "components/responsive/OnDesktop"
@@ -197,6 +198,7 @@ export default function Layout(props: LayoutProps) {
>
}>
+