From f6212acf16454657e35f7ea1f06bfb44e40fe848 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 5 Jun 2026 17:33:52 +0200 Subject: [PATCH] feat: add content health checking feature and update related components --- l10n/bundle.l10n.json | 1 + src/listeners/panel/DataListener.ts | 2 +- src/localization/localization.enum.ts | 6 +++++- src/panelWebView/ViewPanel.tsx | 7 ++++--- .../components/ContentHealth/ContentHealth.tsx | 10 +++++++--- src/panelWebView/hooks/useMessages.tsx | 6 +++++- 6 files changed, 23 insertions(+), 9 deletions(-) diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 69bf748d..6c6b3729 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -530,6 +530,7 @@ "panel.contentHealth.readability.hint.word": "Replace multi-syllable words with simpler alternatives.", "panel.contentHealth.title": "Content Health", "panel.contentHealth.noIssues": "No content health issues found.", + "panel.contentHealth.checking": "Analyzing content health...", "panel.contentHealth.readability.label": "Readability", "panel.contentHealth.readability.level.veryEasy": "Very Easy", "panel.contentHealth.readability.level.easy": "Easy", diff --git a/src/listeners/panel/DataListener.ts b/src/listeners/panel/DataListener.ts index d8e4541e..e3525872 100644 --- a/src/listeners/panel/DataListener.ts +++ b/src/listeners/panel/DataListener.ts @@ -180,7 +180,7 @@ export class DataListener extends BaseListener { `You are helping me improve readability for this article.`, objective, `Preserve meaning, markdown structure, links, code blocks, and front matter unchanged.`, - `Return revised markdown body suggestions and explain key edits.` + `Update the article content and explain the key edits you made.` ].join('\n\n'); try { diff --git a/src/localization/localization.enum.ts b/src/localization/localization.enum.ts index 361a7716..eec34d83 100644 --- a/src/localization/localization.enum.ts +++ b/src/localization/localization.enum.ts @@ -1724,6 +1724,10 @@ export enum LocalizationKey { * No content health issues found. */ panelContentHealthNoIssues = 'panel.contentHealth.noIssues', + /** + * Analyzing content health... + */ + panelContentHealthChecking = 'panel.contentHealth.checking', /** * Readability */ @@ -1749,7 +1753,7 @@ export enum LocalizationKey { */ panelContentHealthReadabilityLevelVeryDifficult = 'panel.contentHealth.readability.level.veryDifficult', /** - * (below threshold) + * (below threshold - {0}) */ panelContentHealthReadabilityBelowThreshold = 'panel.contentHealth.readability.belowThreshold', /** diff --git a/src/panelWebView/ViewPanel.tsx b/src/panelWebView/ViewPanel.tsx index cf8d0994..b2bbee63 100644 --- a/src/panelWebView/ViewPanel.tsx +++ b/src/panelWebView/ViewPanel.tsx @@ -32,7 +32,8 @@ export const ViewPanel: React.FunctionComponent = () => { folderAndFiles, focusElm, unsetFocus, - mode + mode, + contentHealth } = useMessages(); const prevMediaSelection = usePrevious(mediaSelecting); const [scrollY, setScrollY] = useState(0); @@ -130,9 +131,9 @@ export const ViewPanel: React.FunctionComponent = () => { { - !loading && metadata?.contentHealth && ( + !loading && metadata && ( - + ) } diff --git a/src/panelWebView/components/ContentHealth/ContentHealth.tsx b/src/panelWebView/components/ContentHealth/ContentHealth.tsx index cd6f6e61..720c9183 100644 --- a/src/panelWebView/components/ContentHealth/ContentHealth.tsx +++ b/src/panelWebView/components/ContentHealth/ContentHealth.tsx @@ -18,12 +18,16 @@ interface ContentHealthData { } interface Props { - contentHealth: ContentHealthData; + contentHealth: ContentHealthData | undefined; } const ContentHealth: React.FunctionComponent = ({ contentHealth }) => { - if (!contentHealth) { - return null; + if (contentHealth === undefined) { + return ( + +

{localize(LocalizationKey.panelContentHealthChecking)}

+
+ ); } const { internalLinks, brokenExternalLinks, readability, freshnessWarning, minReadability = 0 } = contentHealth; diff --git a/src/panelWebView/hooks/useMessages.tsx b/src/panelWebView/hooks/useMessages.tsx index f550ee10..1c306280 100644 --- a/src/panelWebView/hooks/useMessages.tsx +++ b/src/panelWebView/hooks/useMessages.tsx @@ -14,6 +14,8 @@ import { PanelSettingsAtom } from '../state'; export default function useMessages() { // eslint-disable-next-line @typescript-eslint/no-explicit-any const [metadata, setMetadata] = useState(undefined); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const [contentHealth, setContentHealth] = useState(undefined); const [settings, setSettings] = useRecoilState(PanelSettingsAtom); const [loading, setLoading] = useState(false); const [focusElm, setFocus] = useState(null); @@ -33,10 +35,11 @@ export default function useMessages() { switch (message.command) { case Command.metadata: setMetadata(message.payload); + setContentHealth(undefined); setLoading(false); break; case Command.contentHealth: - setMetadata((prev: any) => prev ? { ...prev, contentHealth: message.payload } : prev); + setContentHealth(message.payload); break; case Command.settings: setSettings(message.payload); @@ -95,6 +98,7 @@ export default function useMessages() { return { metadata, + contentHealth, settings, folderAndFiles, focusElm,