mirror of
https://github.com/wassname/talk.git
synced 2026-08-14 12:50:17 +08:00
Fix UserBox
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
import { commitLocalUpdate, Environment } from "relay-runtime";
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
import { createMutationContainer } from "talk-framework/lib/relay";
|
||||
import { LOCAL_ID } from "talk-framework/lib/relay/withLocalStateContainer";
|
||||
|
||||
export type SignOffMutation = () => Promise<void>;
|
||||
|
||||
export async function commit(
|
||||
environment: Environment,
|
||||
{ localStorage }: TalkContext
|
||||
) {
|
||||
return commitLocalUpdate(environment, store => {
|
||||
const record = store.get(LOCAL_ID)!;
|
||||
record.setValue("", "authToken");
|
||||
localStorage.removeItem("authToken");
|
||||
|
||||
// Force gc to trigger.
|
||||
environment
|
||||
.retain({
|
||||
dataID: "tmp",
|
||||
node: { selections: [] },
|
||||
variables: {},
|
||||
})
|
||||
.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
export const withSignOffMutation = createMutationContainer("signOff", commit);
|
||||
@@ -1,4 +1,3 @@
|
||||
export { withSetViewMutation, SetViewMutation } from "./SetViewMutation";
|
||||
export { withSignInMutation, SignInMutation } from "./SignInMutation";
|
||||
export { withSignUpMutation, SignUpMutation } from "./SignUpMutation";
|
||||
export { withSignOffMutation, SignOffMutation } from "./SignOffMutation";
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Environment } from "relay-runtime";
|
||||
import { TalkContext } from "talk-framework/lib/bootstrap";
|
||||
import { createMutationContainer } from "talk-framework/lib/relay";
|
||||
import signOut from "../rest/signOut";
|
||||
import { commit as setAuthToken } from "./SetAuthTokenMutation";
|
||||
|
||||
export type SignOutMutation = () => Promise<void>;
|
||||
|
||||
export async function commit(environment: Environment, ctx: TalkContext) {
|
||||
await setAuthToken(environment, { authToken: "" }, ctx);
|
||||
await signOut(ctx.rest);
|
||||
}
|
||||
|
||||
export const withSignOutMutation = createMutationContainer("signOut", commit);
|
||||
@@ -3,3 +3,4 @@ export {
|
||||
SetAuthTokenMutation,
|
||||
SetAuthTokenInput,
|
||||
} from "./SetAuthTokenMutation";
|
||||
export { withSignOutMutation, SignOutMutation } from "./SignOutMutation";
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export { default as signIn, SignInInput } from "./signIn";
|
||||
export { default as signUp, SignUpInput } from "./signUp";
|
||||
export { default as signOff } from "./signOff";
|
||||
export { default as signOut } from "./signOut";
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import { RestClient } from "../lib/rest";
|
||||
|
||||
export default function signOff(rest: RestClient) {
|
||||
return rest.fetch("/tenant/auth/local", {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { RestClient } from "../lib/rest";
|
||||
|
||||
export default function signOut(rest: RestClient) {
|
||||
return rest.fetch("/tenant/auth", {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
@@ -4,12 +4,11 @@ import React, { StatelessComponent } from "react";
|
||||
import { Button, Flex, Typography } from "talk-ui/components";
|
||||
|
||||
import MatchMedia from "talk-ui/components/MatchMedia";
|
||||
import { User } from "../containers/UserBoxContainer";
|
||||
import * as styles from "./UserBoxAuthenticated.css";
|
||||
|
||||
export interface UserBoxAuthenticatedProps {
|
||||
onSignOff: () => void;
|
||||
user: User;
|
||||
onSignOut: () => void;
|
||||
username: string;
|
||||
}
|
||||
|
||||
const UserBoxAuthenticated: StatelessComponent<
|
||||
@@ -25,7 +24,7 @@ const UserBoxAuthenticated: StatelessComponent<
|
||||
</Typography>
|
||||
</Localized>
|
||||
<Typography variant="bodyCopyBold" component="span">
|
||||
{props.user.username}
|
||||
{props.username}
|
||||
</Typography>
|
||||
</MatchMedia>
|
||||
</Flex>
|
||||
@@ -40,7 +39,7 @@ const UserBoxAuthenticated: StatelessComponent<
|
||||
color="primary"
|
||||
size="small"
|
||||
variant="underlined"
|
||||
onClick={props.onSignOff}
|
||||
onClick={props.onSignOut}
|
||||
>
|
||||
Sign Out
|
||||
</Button>
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { shallow } from "enzyme";
|
||||
import { noop } from "lodash";
|
||||
import React from "react";
|
||||
|
||||
import { PropTypesOf } from "talk-framework/types";
|
||||
|
||||
import UserBoxUnauthenticated from "./UserBoxUnauthenticated";
|
||||
|
||||
it("renders correctly", () => {
|
||||
const props: PropTypesOf<typeof UserBoxUnauthenticated> = {
|
||||
onSignIn: noop,
|
||||
onRegister: noop,
|
||||
};
|
||||
const wrapper = shallow(<UserBoxUnauthenticated {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -1,25 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
import UserBoxAuthenticated from "talk-stream/components/UserBoxAuthenticated";
|
||||
import { SignOffMutation, withSignOffMutation } from "../../auth/mutations";
|
||||
import { User } from "../containers/UserBoxContainer";
|
||||
|
||||
interface UserBoxAuthenticatedProps {
|
||||
signOff: SignOffMutation;
|
||||
user: User;
|
||||
}
|
||||
|
||||
class UserBoxAuthenticatedContainer extends Component<
|
||||
UserBoxAuthenticatedProps
|
||||
> {
|
||||
private onSignOff = () => {
|
||||
this.props.signOff();
|
||||
};
|
||||
public render() {
|
||||
return (
|
||||
<UserBoxAuthenticated onSignOff={this.onSignOff} user={this.props.user} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withSignOffMutation(UserBoxAuthenticatedContainer);
|
||||
export default enhanced;
|
||||
@@ -14,10 +14,13 @@ it("renders correctly", () => {
|
||||
view: "SIGN_IN",
|
||||
},
|
||||
},
|
||||
user: null,
|
||||
// tslint:disable-next-line:no-empty
|
||||
showAuthPopup: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
setAuthPopupState: async () => {},
|
||||
// tslint:disable-next-line:no-empty
|
||||
signOut: async () => {},
|
||||
};
|
||||
const wrapper = shallow(<UserBoxContainer {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import * as React from "react";
|
||||
import { Component } from "react";
|
||||
import { graphql, withLocalStateContainer } from "talk-framework/lib/relay";
|
||||
import {
|
||||
graphql,
|
||||
withFragmentContainer,
|
||||
withLocalStateContainer,
|
||||
} from "talk-framework/lib/relay";
|
||||
import { UserBoxContainer_user as UserData } from "talk-stream/__generated__/UserBoxContainer_user.graphql";
|
||||
import { UserBoxContainerLocal as Local } from "talk-stream/__generated__/UserBoxContainerLocal.graphql";
|
||||
import {
|
||||
SetAuthPopupStateMutation,
|
||||
@@ -8,30 +13,18 @@ import {
|
||||
withSetAuthPopupStateMutation,
|
||||
withShowAuthPopupMutation,
|
||||
} from "talk-stream/mutations";
|
||||
import { SignOutMutation, withSignOutMutation } from "talk-framework/mutations";
|
||||
import { Popup } from "talk-ui/components";
|
||||
|
||||
import UserBoxUnauthenticated from "talk-stream/components/UserBoxUnauthenticated";
|
||||
import UserBoxAuthenticatedContainer from "../containers/UserBoxAuthenticatedContainer";
|
||||
|
||||
export type USER_ROLE =
|
||||
| "ADMIN"
|
||||
| "COMMENTER"
|
||||
| "MODERATOR"
|
||||
| "STAFF"
|
||||
| "%future added value";
|
||||
|
||||
export interface User {
|
||||
id?: string;
|
||||
username?: string | null;
|
||||
displayName?: string | null;
|
||||
role?: USER_ROLE;
|
||||
}
|
||||
import UserBoxAuthenticated from "../components/UserBoxAuthenticated";
|
||||
|
||||
interface InnerProps {
|
||||
local: Local;
|
||||
user: User | null | undefined;
|
||||
user: UserData | null;
|
||||
showAuthPopup: ShowAuthPopupMutation;
|
||||
setAuthPopupState: SetAuthPopupStateMutation;
|
||||
signOut: SignOutMutation;
|
||||
}
|
||||
|
||||
export class UserBoxContainer extends Component<InnerProps> {
|
||||
@@ -47,10 +40,17 @@ export class UserBoxContainer extends Component<InnerProps> {
|
||||
authPopup: { open, focus, view },
|
||||
},
|
||||
user,
|
||||
signOut,
|
||||
} = this.props;
|
||||
|
||||
if (user) {
|
||||
return <UserBoxAuthenticatedContainer user={user} />;
|
||||
return (
|
||||
<UserBoxAuthenticated
|
||||
onSignOut={signOut}
|
||||
// TODO: why nullable?
|
||||
username={user.username!}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -74,21 +74,30 @@ export class UserBoxContainer extends Component<InnerProps> {
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withSetAuthPopupStateMutation(
|
||||
withShowAuthPopupMutation(
|
||||
withLocalStateContainer<Local>(
|
||||
graphql`
|
||||
fragment UserBoxContainerLocal on Local {
|
||||
authPopup {
|
||||
open
|
||||
focus
|
||||
view
|
||||
const enhanced = withSignOutMutation(
|
||||
withSetAuthPopupStateMutation(
|
||||
withShowAuthPopupMutation(
|
||||
withLocalStateContainer<Local>(
|
||||
graphql`
|
||||
fragment UserBoxContainerLocal on Local {
|
||||
authPopup {
|
||||
open
|
||||
focus
|
||||
view
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)(UserBoxContainer)
|
||||
`
|
||||
)(
|
||||
withFragmentContainer<{ user: UserData | null }>({
|
||||
user: graphql`
|
||||
fragment UserBoxContainer_user on User {
|
||||
username
|
||||
}
|
||||
`,
|
||||
})(UserBoxContainer)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// TODO: (bc) Add fragment here if composing is doable.
|
||||
export default enhanced;
|
||||
|
||||
Reference in New Issue
Block a user