diff --git a/packages/desktop-client/src/components/PrivacyFilter.tsx b/packages/desktop-client/src/components/PrivacyFilter.tsx index 1053ce0ce8..f2968e5eb7 100644 --- a/packages/desktop-client/src/components/PrivacyFilter.tsx +++ b/packages/desktop-client/src/components/PrivacyFilter.tsx @@ -1,8 +1,10 @@ // @ts-strict-ignore -import React, { +import { Children, type ComponentPropsWithRef, type ReactNode, + useLayoutEffect, + useRef, } from 'react'; import { useResponsive } from '@actual-app/components/hooks/useResponsive'; @@ -67,6 +69,36 @@ export function PrivacyFilter({ ); } +type RedactedContentProps = { + children: ReactNode; +}; + +// Component that filters text content to remove non-alphanumeric characters +// This works by intercepting the actual rendered text via a ref and modifying it +function RedactedContent({ children }: RedactedContentProps) { + const containerRef = useRef(null); + + useLayoutEffect(() => { + if (containerRef.current) { + // Walk all text nodes and replace non-alphanumeric characters + const walker = document.createTreeWalker( + containerRef.current, + NodeFilter.SHOW_TEXT, + null, + ); + + let node: Text | null; + while ((node = walker.nextNode() as Text | null)) { + if (node.textContent) { + node.textContent = node.textContent.replace(/[^a-zA-Z0-9]/g, '*'); + } + } + } + }, [children]); + + return
{children}
; +} + function PrivacyOverlay({ children, ...props }) { const { style, ...restProps } = props; @@ -122,7 +154,7 @@ function PrivacyOverlay({ children, ...props }) { width: '100%', })} > - {children} + {children} ); diff --git a/upcoming-release-notes/6438.md b/upcoming-release-notes/6438.md new file mode 100644 index 0000000000..e7ff22846a --- /dev/null +++ b/upcoming-release-notes/6438.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [StephenBrown2] +--- + +Fixes redacted content to work with currency symbols