summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2023-02-23 10:15:28 +0100
committerOskar Nyberg <oskar@mullvad.net>2023-02-27 10:57:36 +0100
commit955f1cd2c5ba4594c736cbc0ed49d770400e0062 (patch)
treee6c5ebcf7d62ec6b0dda4abc40d58f90f2cc1fd7 /gui/src
parentf49760525dbd4bfb5e19a0231d1d8b7a41f76ce1 (diff)
downloadmullvadvpn-955f1cd2c5ba4594c736cbc0ed49d770400e0062.tar.xz
mullvadvpn-955f1cd2c5ba4594c736cbc0ed49d770400e0062.zip
Fix back action collision
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/renderer/components/KeyboardNavigation.tsx33
1 files changed, 25 insertions, 8 deletions
diff --git a/gui/src/renderer/components/KeyboardNavigation.tsx b/gui/src/renderer/components/KeyboardNavigation.tsx
index f88b4f31e9..fc11e54699 100644
--- a/gui/src/renderer/components/KeyboardNavigation.tsx
+++ b/gui/src/renderer/components/KeyboardNavigation.tsx
@@ -12,9 +12,15 @@ interface IKeyboardNavigationProps {
// Listens for and handles keyboard shortcuts
export default function KeyboardNavigation(props: IKeyboardNavigationProps) {
const history = useHistory();
- const [backAction, setBackAction] = useState<BackActionFn>();
+ const [backAction, setBackActionImpl] = useState<BackActionFn>();
const location = useLocation();
+ // Since the backaction is now a function we need to make sure it's not called when setting the
+ // state.
+ const setBackAction = useCallback((backAction: BackActionFn | undefined) => {
+ setBackActionImpl(() => backAction);
+ }, []);
+
const handleKeyDown = useCallback(
(event: KeyboardEvent) => {
if (event.key === 'Escape') {
@@ -66,17 +72,28 @@ interface IBackActionProps {
// either by pressing the back button in the navigation bar or by pressing escape.
export function BackAction(props: IBackActionProps) {
const backActionContext = useContext(BackActionContext);
- const [childrenBackAction, setChildrenBackAction] = useState<BackActionFn>();
+ const [childrenBackAction, setChildrenBackActionImpl] = useState<BackActionFn>();
+
+ // Since the backaction is now a function we need to make sure it's not called when setting the
+ // state.
+ const setChildrenBackAction = useCallback((backAction: BackActionFn | undefined) => {
+ setChildrenBackActionImpl(() => backAction);
+ }, []);
- const backActionConfiguration = childrenBackAction ?? props.action;
+ // Each back action needs to be unique to make `removeBackAction` work. This is accomplished by
+ // wrapping it in a callback. This was an issue since `history.pop`, which is commonly used as a
+ // back action, is the same function for every component.
+ const backAction = useCallback(() => {
+ (childrenBackAction ?? props.action)();
+ }, [props.action, childrenBackAction]);
// Every time the action or the disabled property changes the action needs to be reregistered.
useEffect((): (() => void) | void => {
- if (!props.disabled && backActionConfiguration) {
- backActionContext.registerBackAction(backActionConfiguration);
- return () => backActionContext.removeBackAction(backActionConfiguration);
+ if (!props.disabled && backAction) {
+ backActionContext.registerBackAction(backAction);
+ return () => backActionContext.removeBackAction(backAction);
}
- }, [props.disabled, backActionConfiguration]);
+ }, [props.disabled, backAction]);
// Every back action keeps track of the back actions in its subtree. This makes it possible to
// always use the action furthest down in the tree.
@@ -109,7 +126,7 @@ function BackActionTracker(props: IBackActionTracker) {
[backActions],
);
- useEffect(() => props.registerBackAction(() => backActions.at(0)), [backActions]);
+ useEffect(() => props.registerBackAction(backActions.at(0)), [backActions]);
return (
<BackActionContext.Provider value={backActionContext}>