Skip to content

Commit

Permalink
add screen improvements when not logged in (#1828)
Browse files Browse the repository at this point in the history
When logged out, rather than forcing user to register / log in _before_
seeing any kind of add screen, we do it after they see the initial "add
pcd" screen.
  • Loading branch information
rrrliu authored Jul 15, 2024
1 parent 3f6054f commit 402cc63
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 36 deletions.
19 changes: 7 additions & 12 deletions apps/passport-client/components/screens/AddScreen/AddScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import {
} from "@pcd/passport-interface";
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
import { useDispatch, useLoginIfNoSelf, useSelf } from "../../../src/appHooks";
import { useDispatch } from "../../../src/appHooks";
import { validateRequest } from "../../../src/passportRequest";
import { pendingRequestKeys } from "../../../src/sessionStorage";
import { useSyncE2EEStorage } from "../../../src/useSyncE2EEStorage";
import { err } from "../../../src/util";
import { AppContainer } from "../../shared/AppContainer";
Expand All @@ -23,37 +22,33 @@ import { ProveAndAddScreen } from "./ProveAndAddScreen";
export function AddScreen(): JSX.Element | null {
useSyncE2EEStorage();
const dispatch = useDispatch();
const self = useSelf();
const location = useLocation();
const params = new URLSearchParams(location.search);
const request = validateRequest(params);
const screen = getScreen(request);
const autoAdd = params.get("autoAdd") === "true";
const screen = getScreen(request, autoAdd);

useEffect(() => {
if (screen === null) {
err(dispatch, "Unsupported request", `Expected a PCD ADD request`);
}
}, [dispatch, screen]);

useLoginIfNoSelf(pendingRequestKeys.add, request);

if (!self) {
return null;
}

if (!screen) {
// Need AppContainer to display error
return <AppContainer bg="gray" />;
}
return screen;
}

function getScreen(request: PCDRequest): JSX.Element | null {
function getScreen(request: PCDRequest, autoAdd: boolean): JSX.Element | null {
switch (request.type) {
case PCDRequestType.ProveAndAdd:
return <ProveAndAddScreen request={request as PCDProveAndAddRequest} />;
case PCDRequestType.Add:
return <JustAddScreen request={request as PCDAddRequest} />;
return (
<JustAddScreen autoAdd={autoAdd} request={request as PCDAddRequest} />
);
default:
return null;
}
Expand Down
53 changes: 34 additions & 19 deletions apps/passport-client/components/screens/AddScreen/JustAddScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import {
requestLogToServer
} from "@pcd/passport-interface";
import { getErrorMessage } from "@pcd/util";
import { useCallback, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import styled from "styled-components";
import { appConfig } from "../../../src/appConfig";
import { useDispatch, useIsSyncSettled, useSelf } from "../../../src/appHooks";
import {
clearAllPendingRequests,
pendingRequestKeys
} from "../../../src/sessionStorage";
import { useDeserialized } from "../../../src/useDeserialized";
import { err } from "../../../src/util";
import { Button, H2, Spacer } from "../../core";
import { RippleLoader } from "../../core/RippleLoader";
import { MaybeModal } from "../../modals/Modal";
import { AddedPCD } from "../../shared/AddedPCD";
import { AppContainer } from "../../shared/AppContainer";
Expand All @@ -26,9 +31,11 @@ import { useTensionConfetti } from "../ProtocolWorldsScreens/useTensionConfetti"
* a PCD into their wallet without proving it.
*/
export function JustAddScreen({
request
request,
autoAdd
}: {
request: PCDAddRequest;
autoAdd: boolean; // Automatically add item on load
}): JSX.Element {
const dispatch = useDispatch();
const [added, setAdded] = useState(false);
Expand All @@ -38,14 +45,23 @@ export function JustAddScreen({
const isProtocolWorlds = request.folder === ProtocolWorldsFolderName;
const [ref, setRef] = useState<HTMLElement | null>(null);
const confetti = useTensionConfetti(ref);
const hasAutoAdded = useRef(false);

const onAddClick = useCallback(async () => {
// If not logged in, direct user to log in
if (!self) {
clearAllPendingRequests();
const stringifiedRequest = JSON.stringify(request ?? "");

sessionStorage.setItem(pendingRequestKeys.add, stringifiedRequest);
window.location.href = `/#/login?redirectedFromAction=true&${
pendingRequestKeys.add
}=${encodeURIComponent(stringifiedRequest)}`;
return;
}
try {
// This is mostly for typechecking and should never throw
// because <AddScreen /> checks if the user is logged in
if (!self) {
throw new Error("User must be logged in");
}
await dispatch({
type: "add-pcds",
pcds: [request.pcd],
Expand All @@ -64,26 +80,23 @@ export function JustAddScreen({
} catch (e) {
await err(dispatch, "Error Adding PCD", getErrorMessage(e));
}
}, [
confetti,
dispatch,
request.folder,
request.pcd,
self,
pcd,
isProtocolWorlds
]);
}, [confetti, dispatch, self, pcd, isProtocolWorlds, request]);

useEffect(() => {
if (autoAdd && !hasAutoAdded.current) {
onAddClick();
hasAutoAdded.current = true;
}
}, [autoAdd, onAddClick]);

let content;

if (!syncSettled) {
if (self && !syncSettled) {
return <SyncingPCDs />;
} else if (!added) {
content = (
<>
<H2>
{isProtocolWorlds ? "TENSION DISCOVERED" : "ADD PCD".toUpperCase()}
</H2>
{isProtocolWorlds && <H2>{"TENSION DISCOVERED".toUpperCase()}</H2>}
<Spacer h={16} />
{pcd && (
<PCDCard
Expand All @@ -95,7 +108,7 @@ export function JustAddScreen({
)}
{!isProtocolWorlds && request.folder && (
<div>
PCD will be added to folder:
This item will be added to folder:
<br /> <strong>{request.folder}</strong>
</div>
)}
Expand All @@ -114,6 +127,8 @@ export function JustAddScreen({
} else {
window.location.hash = "#/";
}
} else if (autoAdd) {
content = <RippleLoader />;
} else {
content = <AddedPCD onCloseClick={(): void => window.close()} />;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import { PCDProveAndAddRequest } from "@pcd/passport-interface";
import { PCD, SerializedPCD } from "@pcd/pcd-types";
import { ReactNode, useCallback, useState } from "react";
import styled from "styled-components";
import { useDispatch, useIsSyncSettled } from "../../../src/appHooks";
import {
useDispatch,
useIsSyncSettled,
useLoginIfNoSelf
} from "../../../src/appHooks";
import { safeRedirect } from "../../../src/passportRequest";
import { pendingRequestKeys } from "../../../src/sessionStorage";
import { H2, Spacer } from "../../core";
import { MaybeModal } from "../../modals/Modal";
import { AddedPCD } from "../../shared/AddedPCD";
Expand All @@ -27,6 +32,8 @@ export function ProveAndAddScreen({
SerializedPCD | undefined
>();

useLoginIfNoSelf(pendingRequestKeys.add, request);

const onProve = useCallback(
async (_: PCD | undefined, serializedPCD: SerializedPCD | undefined) => {
if (serializedPCD) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export function LoginInterstitialScreen(): JSX.Element {
console.log("Redirecting to add screen");
const encReq = encodeURIComponent(pendingRequest.value);
clearAllPendingRequests();
navigate("/add?request=" + encReq, { replace: true });
navigate("/add?request=" + encReq + "&autoAdd=true", {
replace: true
});
break;
}
case "halo": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ export function LoginScreen(): JSX.Element {
<TextCenter>
<H2>ZUPASS</H2>
<Spacer h={24} />
To complete this request, you need to either log into your existing
Zupass account, or create a new one.
To complete this request, please login or register with your email
below.
</TextCenter>
</>
) : (
Expand Down
7 changes: 6 additions & 1 deletion apps/passport-client/components/shared/AppHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useCallback } from "react";
import { IoMdSettings } from "react-icons/io";
import { MdInfo, MdOutlineQrCodeScanner, MdRssFeed } from "react-icons/md";
import styled from "styled-components";
import { useDispatch, useSubscriptions } from "../../src/appHooks";
import { useDispatch, useSelf, useSubscriptions } from "../../src/appHooks";
import { AppState } from "../../src/state";

export const AppHeader = React.memo(AppHeaderImpl);
Expand All @@ -18,6 +18,7 @@ function AppHeaderImpl({
isProveOrAddScreen?: boolean;
}): JSX.Element {
const dispatch = useDispatch();
const self = useSelf();

const setModal = useCallback(
(modal: AppState["modal"]) =>
Expand All @@ -44,6 +45,10 @@ function AppHeaderImpl({
);
const subscriptions = useSubscriptions();

if (!self) {
return <AppHeaderWrap>{children}</AppHeaderWrap>;
}

return (
<AppHeaderWrap>
<CircleButton diameter={34} padding={8} onClick={openInfo}>
Expand Down

0 comments on commit 402cc63

Please sign in to comment.