Swipe to dismiss notifications (#4606)

* Swipe to dismiss notifications

* Release notes

* Update VRT

* Dummy commit

* Make notification swipe a bit snappier

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Joel Jeremy Marquez
2025-03-11 14:35:01 -07:00
committed by GitHub
parent bf154db3d6
commit 3ecfb4be7e
40 changed files with 57 additions and 4 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -63,6 +63,7 @@
"react-simple-pull-to-refresh": "^1.3.3",
"react-spring": "^9.7.3",
"react-stately": "^3.33.0",
"react-swipeable": "^7.0.2",
"react-virtualized-auto-sizer": "^1.0.21",
"recharts": "^2.10.4",
"remark-gfm": "^3.0.1",

View File

@@ -7,6 +7,8 @@ import React, {
type CSSProperties,
} from 'react';
import { useTranslation } from 'react-i18next';
import { animated, useSpring } from 'react-spring';
import { useSwipeable } from 'react-swipeable';
import { Button, ButtonWithLoading } from '@actual-app/components/button';
import { useResponsive } from '@actual-app/components/hooks/useResponsive';
@@ -132,17 +134,51 @@ function Notification({
? { minHeight: styles.mobileMinHeight }
: {};
const [isSwiped, setIsSwiped] = useState(false);
const [spring, api] = useSpring(() => ({ x: 0, opacity: 1 }));
const swipeHandlers = useSwipeable({
onSwiping: ({ deltaX }) => {
if (!isSwiped) {
api.start({ x: deltaX });
}
},
onSwiped: ({ velocity, deltaX }) => {
// Distance to trigger deletion
const threshold = 100;
const direction = deltaX > 0 ? 1 : -1;
if (Math.abs(deltaX) > threshold || velocity > 0.5) {
// Animate out & remove item after animation
api.start({
x: direction * 1000,
opacity: 0,
onRest: onRemove,
});
setIsSwiped(true);
} else {
// Reset position if not swiped far enough
api.start({ x: 0 });
}
},
trackMouse: true,
});
return (
<View
<animated.div
role="alert"
style={{
...spring,
marginTop: 10,
color: positive
? theme.noticeText
: error
? theme.errorTextDark
: theme.warningTextDark,
// Prevents scrolling conflicts
touchAction: 'none',
}}
{...swipeHandlers}
>
<Stack
align="center"
@@ -237,10 +273,10 @@ function Notification({
<Button
variant="bare"
aria-label={t('Close')}
style={{ flexShrink: 0, color: 'currentColor' }}
style={{ padding: 10, color: 'currentColor' }}
onPress={onRemove}
>
<SvgDelete style={{ width: 9, height: 9, color: 'currentColor' }} />
<SvgDelete style={{ width: 10, height: 10 }} />
</Button>
</Stack>
{overlayLoading && (
@@ -261,7 +297,7 @@ function Notification({
/>
</View>
)}
</View>
</animated.div>
);
}

View File

@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [joel-jeremy]
---
Swipe left/right to dismiss notifications.

View File

@@ -198,6 +198,7 @@ __metadata:
react-simple-pull-to-refresh: "npm:^1.3.3"
react-spring: "npm:^9.7.3"
react-stately: "npm:^3.33.0"
react-swipeable: "npm:^7.0.2"
react-virtualized-auto-sizer: "npm:^1.0.21"
recharts: "npm:^2.10.4"
remark-gfm: "npm:^3.0.1"
@@ -20087,6 +20088,15 @@ __metadata:
languageName: node
linkType: hard
"react-swipeable@npm:^7.0.2":
version: 7.0.2
resolution: "react-swipeable@npm:7.0.2"
peerDependencies:
react: ^16.8.3 || ^17 || ^18 || ^19.0.0 || ^19.0.0-rc
checksum: 10/c142190244865c321751b0ca5f14ac186cf8a5d49bd577b16b1d22ea4f673d1e85cd7ad1962736be4575df320a6081c2b2b36799236c777b1a3ffb8682f4993c
languageName: node
linkType: hard
"react-transition-group@npm:2.9.0":
version: 2.9.0
resolution: "react-transition-group@npm:2.9.0"