Skip to content

Commit

Permalink
feat: passcode login as modal
Browse files Browse the repository at this point in the history
  • Loading branch information
jimcase committed Apr 29, 2024
1 parent 238b6d2 commit 212b6a0
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 46 deletions.
2 changes: 1 addition & 1 deletion src/locales/en/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@
}
]
},
"passcodelogin": {
"lockmodal": {
"title": "Welcome back",
"description": "Please enter your passcode to login",
"error": "Incorrect passcode",
Expand Down
9 changes: 1 addition & 8 deletions src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,8 @@ import { AuthenticatedRouteProps } from "./routes.types";
const AuthenticatedRoute: React.FC<AuthenticatedRouteProps> = (props) => {
const authentication = useAppSelector(getAuthentication);
const location = useLocation();
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(
authentication.loggedIn
);

useEffect(() => {
setIsAuthenticated(authentication.loggedIn);
}, [authentication.loggedIn]);

return isAuthenticated ? (
return authentication.loggedIn ? (
<Route
{...props}
component={props.component}
Expand Down
4 changes: 4 additions & 0 deletions src/ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { SetUserName } from "./components/SetUserName";
import { TabsRoutePath } from "../routes/paths";
import { MobileHeaderPreview } from "./components/MobileHeaderPreview";
import { CustomToast } from "./components/CustomToast/CustomToast";
import { LockModal } from "./components/LockModal/LockModal";

setupIonicReact();

Expand All @@ -34,6 +35,8 @@ const App = () => {
const [showScan, setShowScan] = useState(false);
const [showToast, setShowToast] = useState(false);

const [lockModalIsOpen, setLockModalIsOpen] = useState(true);

const isPreviewMode = useMemo(
() => new URLSearchParams(window.location.search).has("browserPreview"),
[]
Expand Down Expand Up @@ -97,6 +100,7 @@ const App = () => {
/>
<IncomingRequest />
<Settings />
<LockModal isOpen={authentication.loggedIn} />
<CustomToast
toastMsg={toastMsg}
showToast={showToast}
Expand Down
71 changes: 49 additions & 22 deletions src/ui/components/AppWrapper/AppWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,29 +108,71 @@ const keriAcdcChangeHandler = async (
}
};

const ACTIVITY_TIMEOUT = 60000; // 60 secs
const ACTIVITY_BACKGROUND_TIMEOUT = 3000;

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

let timer: NodeJS.Timeout;
const ACTIVITY_TIMEOUT = 15000;
//let timer: NodeJS.Timeout;
const timeoutDuration = ACTIVITY_TIMEOUT;
/*
useEffect(() => {
const handleActivity = () => {
clearTimeout(timer);
timer = setTimeout(() => {
console.log("lets lock");
console.log("timeoutDuration");
console.log(timeoutDuration);
dispatch(logout());
}, ACTIVITY_TIMEOUT);
}, timeoutDuration);
};
const startBackgroundTimer = () => {
const handleAppStateChange = ({ isActive }: {isActive:boolean}) => {
console.log("handleAppStateChange");
console.log(isActive);
if (isActive) {
timeoutDuration = ACTIVITY_TIMEOUT;
} else {
timeoutDuration = ACTIVITY_TIMEOUT / 2;
}
handleActivity();
};
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 () => {
App.removeAllListeners();
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);
};
}, []);
*/

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

window.addEventListener("load", handleActivity);
Expand All @@ -142,21 +184,6 @@ const AppWrapper = (props: { children: ReactNode }) => {
document.addEventListener("keydown", handleActivity);
document.addEventListener("scroll", handleActivity);

App.addListener("appStateChange", (state) => {
if (!state.isActive) {
startBackgroundTimer();
} else {
handleActivity();
}
});

App.addListener("pause", () => {
startBackgroundTimer();
});
App.addListener("resume", () => {
handleActivity();
});

return () => {
window.removeEventListener("load", handleActivity);
document.removeEventListener("mousemove", handleActivity);
Expand Down
55 changes: 55 additions & 0 deletions src/ui/components/LockModal/LockModal.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
ion-modal.lock-modal {
display: flex;
flex-direction: column;
justify-content: end;
--height: auto;

.responsive-page-content {
justify-content: space-evenly;

.lock-modal-title,
.lock-modal-description {
text-align: center;
}

.lock-modal-title {
margin-top: 4rem;

@media screen and (min-height: 300px) and (max-height: 550px) {
margin-top: 2rem;
}
}
}

.page-header {
ion-toolbar {
--background: transparent;
}
}

&::part(content) {
height: 100%;
}

p *:nth-child(2) {
margin-left: 0.5rem;
}

ion-toolbar {
--min-height: 4rem;

h2 {
margin: 0 auto;
}

&.md {
ion-buttons {
min-width: calc(var(--scale-w) * 14);
}

ion-title {
width: auto;
}
}
}
}
23 changes: 23 additions & 0 deletions src/ui/components/LockModal/LockModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { render, waitFor, fireEvent } from "@testing-library/react";
import { act } from "react-dom/test-utils";
import { LockModal } from "./LockModal";

describe("Terms and conditions screen", () => {
test("User can close the modal by clicking on the backdrop", async () => {
const mockSetIsOpen = jest.fn();
const { getByTestId } = render(<LockModal isOpen={true} />);

await waitFor(() => {
expect(getByTestId("terms-of-use-modal")).toBeVisible();
});

const backdrop = document.querySelector("ion-backdrop");
act(() => {
backdrop && fireEvent.click(backdrop);
});

await waitFor(() => {
expect(backdrop).not.toBeInTheDocument();
});
});
});

0 comments on commit 212b6a0

Please sign in to comment.