Skip to content

Commit

Permalink
Privacy mode: instead of blurring, use an illegible font (#3376) (#3377)
Browse files Browse the repository at this point in the history
* Privacy mode: instead of blurring, use an illegible font (#3376)

* Privacy mode: no layout shift when switching mode

* fix(Spending): update for latest PrivacyFilter

* refactor(PrivacyFilter): use CSS :hover

* chore(PrivacyFilter): no privacy mode BudgetCell height regression...

#3377

* chore(GroupMonth): drop no-impact PrivacyFilter styles
  • Loading branch information
olets authored Sep 27, 2024
1 parent 4373f4d commit 686ce5b
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 68 deletions.
1 change: 1 addition & 0 deletions packages/desktop-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"build"
],
"devDependencies": {
"@fontsource/redacted-script": "^5.0.21",
"@juggle/resize-observer": "^3.4.0",
"@playwright/test": "1.41.1",
"@rollup/plugin-inject": "^5.0.5",
Expand Down
86 changes: 54 additions & 32 deletions packages/desktop-client/src/components/PrivacyFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// @ts-strict-ignore
import React, {
useState,
useCallback,
Children,
type ComponentPropsWithRef,
type ReactNode,
} from 'react';

import { css } from 'glamor';

import { usePrivacyMode } from '../hooks/usePrivacyMode';
import { useResponsive } from '../ResponsiveProvider';

Expand Down Expand Up @@ -44,11 +44,9 @@ export function ConditionalPrivacyFilter({

type PrivacyFilterProps = ComponentPropsWithRef<typeof View> & {
activationFilters?: (boolean | (() => boolean))[];
blurIntensity?: number;
};
export function PrivacyFilter({
activationFilters,
blurIntensity,
children,
...props
}: PrivacyFilterProps) {
Expand All @@ -63,46 +61,70 @@ export function PrivacyFilter({
typeof value === 'boolean' ? value : value(),
));

const blurAmount = blurIntensity != null ? `${blurIntensity}px` : '3px';

return !activate ? (
<>{Children.toArray(children)}</>
) : (
<BlurredOverlay blurIntensity={blurAmount} {...props}>
{children}
</BlurredOverlay>
<PrivacyOverlay {...props}>{children}</PrivacyOverlay>
);
}

function BlurredOverlay({ blurIntensity, children, ...props }) {
const [hovered, setHovered] = useState(false);
const onHover = useCallback(() => setHovered(true), [setHovered]);
const onHoverEnd = useCallback(() => setHovered(false), [setHovered]);

const blurStyle = {
...(!hovered && {
filter: `blur(${blurIntensity})`,
WebkitFilter: `blur(${blurIntensity})`,
// To fix blur performance issue in Safari.
// https://graffino.com/til/CjT2jrcLHP-how-to-fix-filter-blur-performance-issue-in-safari
transform: `translate3d(0, 0, 0)`,
}),
};

function PrivacyOverlay({ children, ...props }) {
const { style, ...restProps } = props;

return (
<View
style={{
display: style?.display ? style.display : 'inline-flex',
...blurStyle,
...style,
}}
onPointerEnter={onHover}
onPointerLeave={onHoverEnd}
className={`${css(
[
{
display: 'inline-flex',
flexGrow: 1,
position: 'relative',
' > div:first-child': {
opacity: 0,
},
' > div:nth-child(2)': {
display: 'flex',
},
'&:hover': {
' > div:first-child': {
opacity: 1,
},
' > div:nth-child(2)': {
display: 'none',
},
},
},
],
style,
)}`}
{...restProps}
>
{children}
<div
className={`${css([
{
display: 'flex',
flexGrow: 1,
},
])}`}
>
{children}
</div>

<div
aria-hidden="true"
className={`${css({
flexDirection: 'column',
fontFamily: 'Redacted Script',
height: '100%',
inset: 0,
justifyContent: 'center',
pointerEvents: 'none',
position: 'absolute',
width: '100%',
})}`}
>
{children}
</div>
</View>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,6 @@ export const ExpenseGroupMonth = memo(function ExpenseGroupMonth({
valueProps={{
binding: envelopeBudget.groupBalance(id),
type: 'financial',
privacyFilter: {
style: {
paddingRight: styles.monthRightPadding,
},
},
}}
/>
</View>
Expand Down Expand Up @@ -431,11 +426,6 @@ export function IncomeGroupMonth({ month }: IncomeGroupMonthProps) {
valueProps={{
binding: envelopeBudget.groupIncomeReceived,
type: 'financial',
privacyFilter: {
style: {
paddingRight: styles.monthRightPadding,
},
},
}}
/>
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ export function ToBudgetAmount({
offset={3}
triggerProps={{ isDisabled: isTotalsListTooltipDisabled }}
>
<PrivacyFilter blurIntensity={7}>
<PrivacyFilter
style={{
textAlign: 'center',
}}
>
<Block
onClick={onClick}
data-cellname={sheetName}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,6 @@ export const GroupMonth = memo(function GroupMonth({
valueProps={{
binding: trackingBudget.groupBalance(id),
type: 'financial',
privacyFilter: {
style: {
paddingRight: styles.monthRightPadding,
},
},
}}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@ export function Saved({ projected, style }: SavedProps) {
},
])}`}
>
<PrivacyFilter blurIntensity={7}>
{format(saved, 'financial')}
</PrivacyFilter>
<PrivacyFilter>{format(saved, 'financial')}</PrivacyFilter>
</View>
</Tooltip>
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ export function ReportSummary({
fontWeight: 800,
}}
>
<PrivacyFilter blurIntensity={7}>
{amountToCurrency(data[balanceTypeOp])}
</PrivacyFilter>
<PrivacyFilter>{amountToCurrency(data[balanceTypeOp])}</PrivacyFilter>
</Text>
<Text style={{ fontWeight: 600 }}>For this time period</Text>
</View>
Expand Down Expand Up @@ -154,7 +152,7 @@ export function ReportSummary({
fontWeight: 800,
}}
>
<PrivacyFilter blurIntensity={7}>
<PrivacyFilter>
{!isNaN(average) && integerToCurrency(Math.round(average))}
</PrivacyFilter>
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ export function CustomReport() {
left={<Block>{balanceType}:</Block>}
right={
<Text>
<PrivacyFilter blurIntensity={5}>
<PrivacyFilter>
{amountToCurrency(data[balanceTypeOp])}
</PrivacyFilter>
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,7 @@ function NetWorthInner({ widget }) {
<View
style={{ ...styles.largeText, fontWeight: 400, marginBottom: 5 }}
>
<PrivacyFilter blurIntensity={5}>
{integerToCurrency(data.netWorth)}
</PrivacyFilter>
<PrivacyFilter>{integerToCurrency(data.netWorth)}</PrivacyFilter>
</View>
<PrivacyFilter>
<Change amount={data.totalChange} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ function SpendingInternal({ widget }: SpendingInternalProps) {
}
right={
<Text style={{ fontWeight: 600 }}>
<PrivacyFilter blurIntensity={5}>
<PrivacyFilter>
{amountToCurrency(
Math.abs(data.intervalData[todayDay].compare),
)}
Expand All @@ -494,7 +494,7 @@ function SpendingInternal({ widget }: SpendingInternalProps) {
}
right={
<Text style={{ fontWeight: 600 }}>
<PrivacyFilter blurIntensity={5}>
<PrivacyFilter>
{amountToCurrency(
Math.abs(data.intervalData[todayDay].compareTo),
)}
Expand All @@ -515,7 +515,7 @@ function SpendingInternal({ widget }: SpendingInternalProps) {
}
right={
<Text style={{ fontWeight: 600 }}>
<PrivacyFilter blurIntensity={5}>
<PrivacyFilter>
{amountToCurrency(
Math.abs(data.intervalData[todayDay].budget),
)}
Expand All @@ -535,7 +535,7 @@ function SpendingInternal({ widget }: SpendingInternalProps) {
}
right={
<Text style={{ fontWeight: 600 }}>
<PrivacyFilter blurIntensity={5}>
<PrivacyFilter>
{amountToCurrency(
Math.abs(data.intervalData[todayDay].average),
)}
Expand Down
5 changes: 0 additions & 5 deletions packages/desktop-client/src/components/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,6 @@ export function Cell({
privacyFilter={mergeConditionalPrivacyFilterProps(
{
activationFilters: [!focused, !exposed],
style: {
position: 'absolute',
width: '100%',
height: '100%',
},
},
privacyFilter,
)}
Expand Down
2 changes: 2 additions & 0 deletions packages/desktop-client/src/fonts.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
$inter-font-path: '../../../node_modules/inter-ui/Inter (web)'
);
@include variable.default;

@import "@fontsource/redacted-script";
6 changes: 6 additions & 0 deletions upcoming-release-notes/3377.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [olets]
---

Privacy mode: instead of blurring, use an illegible font (#3376)
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@actual-app/web@workspace:packages/desktop-client"
dependencies:
"@fontsource/redacted-script": "npm:^5.0.21"
"@juggle/resize-observer": "npm:^3.4.0"
"@playwright/test": "npm:1.41.1"
"@rollup/plugin-inject": "npm:^5.0.5"
Expand Down Expand Up @@ -1846,6 +1847,13 @@ __metadata:
languageName: node
linkType: hard

"@fontsource/redacted-script@npm:^5.0.21":
version: 5.0.21
resolution: "@fontsource/redacted-script@npm:5.0.21"
checksum: 10/93f506c9e8df827ab1872d433a09079c592f3a20a1c36b9a168e68377967d3d1d282fffd51bee973c2ecb253316ff4641d244f8f05242e4aa968a1eb14d065eb
languageName: node
linkType: hard

"@formatjs/ecma402-abstract@npm:1.15.0":
version: 1.15.0
resolution: "@formatjs/ecma402-abstract@npm:1.15.0"
Expand Down

0 comments on commit 686ce5b

Please sign in to comment.