Skip to content

Commit

Permalink
feat: add useActivityTimer hook for locking the app
Browse files Browse the repository at this point in the history
  • Loading branch information
jimcase committed May 7, 2024
1 parent 6ade5d0 commit 63a1a82
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 37 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@capacitor-community/barcode-scanner": "^4.0.1",
"@capacitor-community/sqlite": "^5.5.0",
"@capacitor/android": "^5.0.0",
"@capacitor/app": "^5.0.7",
"@capacitor/clipboard": "^5.0.0",
"@capacitor/core": "^5.0.0",
"@capacitor/ios": "^5.0.0",
Expand Down
41 changes: 4 additions & 37 deletions src/ui/components/AppWrapper/AppWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ import { CredentialStatus } from "../../../core/agent/services/credentialService
import { FavouriteIdentifier } from "../../../store/reducers/identifiersCache/identifiersCache.types";
import "./AppWrapper.scss";
import { ConfigurationService } from "../../../core/configuration";
import { App } from "@capacitor/app";
import { PreferencesStorageItem } from "../../../core/storage/preferences/preferencesStorage.type";
import { useActivityTimer } from "./hooks/useActivityTimer";

const connectionStateChangedHandler = async (
event: ConnectionStateChangedEvent,
Expand Down Expand Up @@ -106,47 +108,12 @@ const acdcChangeHandler = async (
}
};

let ACTIVITY_TIMEOUT = 60000; // 1min
if (process.env.NODE_ENV === "development") {
ACTIVITY_TIMEOUT = 3600000; // 1h
}

const AppWrapper = (props: { children: ReactNode }) => {
const dispatch = useAppDispatch();
const authentication = useAppSelector(getAuthentication);
const [agentInitErr, setAgentInitErr] = useState(false);

let timer: NodeJS.Timeout;
useEffect(() => {
const handleActivity = () => {
clearTimeout(timer);
timer = setTimeout(() => {
dispatch(logout());
}, ACTIVITY_TIMEOUT);
};

// TODO: detect appStateChange in android and ios to reduce the ACTIVITY_TIMEOUT
// App.addListener("appStateChange", handleAppStateChange);
window.addEventListener("load", handleActivity);
document.addEventListener("mousemove", handleActivity);
document.addEventListener("touchstart", handleActivity);
document.addEventListener("touchmove", handleActivity);
document.addEventListener("click", handleActivity);
document.addEventListener("focus", handleActivity);
document.addEventListener("keydown", handleActivity);
document.addEventListener("scroll", handleActivity);

return () => {
window.removeEventListener("load", handleActivity);
document.removeEventListener("mousemove", handleActivity);
document.removeEventListener("touchstart", handleActivity);
document.removeEventListener("touchmove", handleActivity);
document.removeEventListener("click", handleActivity);
document.removeEventListener("focus", handleActivity);
document.removeEventListener("keydown", handleActivity);
clearTimeout(timer);
};
}, []);
useActivityTimer();
//const [activityTimeout, setActivityTimeout] = useState(process.env.NODE_ENV === "development" ? 3600000 : 60000);

useEffect(() => {
initApp();
Expand Down
74 changes: 74 additions & 0 deletions src/ui/components/AppWrapper/hooks/useActivityTimer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useEffect, useRef, useState } from "react";
import { App } from "@capacitor/app";
import { useAppDispatch } from "../../../../store/hooks";
import { logout } from "../../../../store/reducers/stateCache";

const timeout = process.env.NODE_ENV === "development" ? 3600000 : 60000; // 1h/1min
const pauseTimeout = timeout / 2;
const useActivityTimer = () => {
const dispatch = useAppDispatch();
const [pauseTimestamp, setPauseTimestamp] = useState(0);
const timer = useRef<NodeJS.Timeout | null>(null);

const clearTimer = () => {
if (timer.current) {
clearTimeout(timer.current);
}
};

const setActivityTimer = () => {
clearTimer();
timer.current = setTimeout(() => {
dispatch(logout());
}, timeout);
};

const handleActivity = () => {
setActivityTimer();
};

useEffect(() => {
const pauseListener = App.addListener("pause", () => {
const now = new Date().getTime();
setPauseTimestamp(now);
});

const resumeListener = App.addListener("resume", () => {
const now = new Date().getTime();
if (now - pauseTimestamp > pauseTimeout) {
dispatch(logout());
}
});

return () => {
pauseListener.remove();
resumeListener.remove();
clearTimer();
};
}, []);

useEffect(() => {
const events = [
"load",
"mousemove",
"touchstart",
"touchmove",
"click",
"focus",
"keydown",
"scroll",
];
events.forEach((event) => {
window.addEventListener(event, handleActivity);
});

return () => {
events.forEach((event) => {
window.removeEventListener(event, handleActivity);
});
clearTimer();
};
}, []);
};

export { useActivityTimer };

0 comments on commit 63a1a82

Please sign in to comment.