From fe7b734b2cdd5938ed67c5f68f054f7fd01a6715 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Wed, 8 Aug 2018 01:04:25 +0200 Subject: [PATCH] Add UserBox --- src/core/client/embed/index.html | 6 ++ src/core/client/stream/components/App.css | 1 + .../stream/components/PostCommentForm.css | 4 + .../stream/components/PostCommentForm.tsx | 2 +- src/core/client/stream/components/Stream.tsx | 6 +- src/core/client/stream/components/UserBox.css | 3 + src/core/client/stream/components/UserBox.tsx | 40 +++++++++ .../__snapshots__/Stream.spec.tsx.snap | 21 +++-- .../stream/containers/UserBoxContainer.tsx | 72 ++++++++++++++++ src/core/client/stream/local/constants.ts | 3 + .../client/stream/local/initLocalState.ts | 21 ++++- src/core/client/stream/local/local.graphql | 15 +++- .../SetAuthPopupStateMutation.spec.ts | 52 ++++++++++++ .../mutations/SetAuthPopupStateMutation.ts | 38 +++++++++ .../SetNetworkStatusMutation.spec.ts | 1 - .../mutations/ShowAuthPopupMutation.spec.ts | 42 ++++++++++ .../stream/mutations/ShowAuthPopupMutation.ts | 36 ++++++++ src/core/client/stream/mutations/index.ts | 8 ++ .../test/__snapshots__/loadMore.spec.tsx.snap | 82 ++++++++++++++++++- .../__snapshots__/permalinkView.spec.tsx.snap | 41 +++++++++- ...permalinkViewCommentNotFound.spec.tsx.snap | 41 +++++++++- .../__snapshots__/renderReplies.spec.tsx.snap | 41 +++++++++- .../__snapshots__/renderStream.spec.tsx.snap | 41 +++++++++- .../showAllReplies.spec.tsx.snap | 82 ++++++++++++++++++- .../client/stream/test/createEnvironment.ts | 34 ++++++++ src/core/client/stream/test/loadMore.spec.tsx | 16 ++-- .../client/stream/test/permalinkView.spec.tsx | 13 ++- .../test/permalinkViewAssetNotFound.spec.tsx | 14 ++-- .../permalinkViewCommentNotFound.spec.tsx | 13 ++- .../client/stream/test/renderReplies.spec.tsx | 13 ++- .../client/stream/test/renderStream.spec.tsx | 13 ++- .../stream/test/showAllReplies.spec.tsx | 13 ++- .../client/ui/components/Button/Button.css | 4 +- src/core/client/ui/components/Flex/Flex.css | 3 - src/core/client/ui/components/Flex/Flex.tsx | 4 + src/core/client/ui/components/Popup/Popup.ts | 3 + .../ui/components/Typography/Typography.css | 4 + .../ui/components/Typography/Typography.mdx | 1 + .../ui/components/Typography/Typography.tsx | 2 + src/core/client/ui/shared/typography.css | 5 ++ .../server/graph/tenant/schema/schema.graphql | 3 +- 41 files changed, 773 insertions(+), 84 deletions(-) create mode 100644 src/core/client/stream/components/UserBox.css create mode 100644 src/core/client/stream/components/UserBox.tsx create mode 100644 src/core/client/stream/containers/UserBoxContainer.tsx create mode 100644 src/core/client/stream/mutations/SetAuthPopupStateMutation.spec.ts create mode 100644 src/core/client/stream/mutations/SetAuthPopupStateMutation.ts create mode 100644 src/core/client/stream/mutations/ShowAuthPopupMutation.spec.ts create mode 100644 src/core/client/stream/mutations/ShowAuthPopupMutation.ts create mode 100644 src/core/client/stream/test/createEnvironment.ts diff --git a/src/core/client/embed/index.html b/src/core/client/embed/index.html index 297768c75..10106ff8c 100644 --- a/src/core/client/embed/index.html +++ b/src/core/client/embed/index.html @@ -6,6 +6,12 @@ + diff --git a/src/core/client/stream/components/App.css b/src/core/client/stream/components/App.css index 3f61a7cae..9836a4fcf 100644 --- a/src/core/client/stream/components/App.css +++ b/src/core/client/stream/components/App.css @@ -2,6 +2,7 @@ :global { body { margin: "0"; + padding: 2px; /* Support for all WebKit browsers. */ -webkit-font-smoothing: antialiased; diff --git a/src/core/client/stream/components/PostCommentForm.css b/src/core/client/stream/components/PostCommentForm.css index 7e3ef2e15..e813f4ea7 100644 --- a/src/core/client/stream/components/PostCommentForm.css +++ b/src/core/client/stream/components/PostCommentForm.css @@ -1,3 +1,7 @@ +.root { + width: 100%; +} + .textarea { composes: bodyCopy from "talk-ui/shared/typography.css"; diff --git a/src/core/client/stream/components/PostCommentForm.tsx b/src/core/client/stream/components/PostCommentForm.tsx index badcbaca8..72bc0ad70 100644 --- a/src/core/client/stream/components/PostCommentForm.tsx +++ b/src/core/client/stream/components/PostCommentForm.tsx @@ -20,7 +20,7 @@ export interface PostCommentFormProps { const PostCommentForm: StatelessComponent = props => (
{({ handleSubmit, submitting }) => ( - + {({ input, meta }) => (
diff --git a/src/core/client/stream/components/Stream.tsx b/src/core/client/stream/components/Stream.tsx index ef1ed5bda..7f1ea183c 100644 --- a/src/core/client/stream/components/Stream.tsx +++ b/src/core/client/stream/components/Stream.tsx @@ -7,6 +7,7 @@ import { Button, Flex } from "talk-ui/components"; import CommentContainer from "../containers/CommentContainer"; import PostCommentFormContainer from "../containers/PostCommentFormContainer"; import ReplyListContainer from "../containers/ReplyListContainer"; +import UserBoxContainer from "../containers/UserBoxContainer"; import * as styles from "./Stream.css"; export interface StreamProps { @@ -20,7 +21,8 @@ export interface StreamProps { const Stream: StatelessComponent = props => { return ( -
+ + = props => { )} -
+ ); }; diff --git a/src/core/client/stream/components/UserBox.css b/src/core/client/stream/components/UserBox.css new file mode 100644 index 000000000..272b33bdb --- /dev/null +++ b/src/core/client/stream/components/UserBox.css @@ -0,0 +1,3 @@ +.joinText { + margin-right: var(--spacing-unit); +} diff --git a/src/core/client/stream/components/UserBox.tsx b/src/core/client/stream/components/UserBox.tsx new file mode 100644 index 000000000..cff9dcb0a --- /dev/null +++ b/src/core/client/stream/components/UserBox.tsx @@ -0,0 +1,40 @@ +import React, { StatelessComponent } from "react"; + +import { Button, Flex, Typography } from "talk-ui/components"; + +import * as styles from "./UserBox.css"; + +export interface UserBoxProps { + onSignIn: () => void; + onRegister: () => void; +} + +const UserBox: StatelessComponent = props => { + return ( + + + Join the conversation + + + | + + + + + ); +}; + +export default UserBox; diff --git a/src/core/client/stream/components/__snapshots__/Stream.spec.tsx.snap b/src/core/client/stream/components/__snapshots__/Stream.spec.tsx.snap index 5da869b02..84cb64ea1 100644 --- a/src/core/client/stream/components/__snapshots__/Stream.spec.tsx.snap +++ b/src/core/client/stream/components/__snapshots__/Stream.spec.tsx.snap @@ -1,9 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders correctly 1`] = ` -
+ @@ -55,13 +58,16 @@ exports[`renders correctly 1`] = ` /> -
+ `; exports[`when there is more disables load more button 1`] = ` -
+ @@ -127,13 +133,16 @@ exports[`when there is more disables load more button 1`] = ` -
+ `; exports[`when there is more renders a load more button 1`] = ` -
+ @@ -199,5 +208,5 @@ exports[`when there is more renders a load more button 1`] = ` -
+ `; diff --git a/src/core/client/stream/containers/UserBoxContainer.tsx b/src/core/client/stream/containers/UserBoxContainer.tsx new file mode 100644 index 000000000..2e780fd61 --- /dev/null +++ b/src/core/client/stream/containers/UserBoxContainer.tsx @@ -0,0 +1,72 @@ +import * as React from "react"; +import { Component } from "react"; + +import { graphql, withLocalStateContainer } from "talk-framework/lib/relay"; +import { UserBoxContainerLocal as Local } from "talk-stream/__generated__/UserBoxContainerLocal.graphql"; +import { + SetAuthPopupStateMutation, + ShowAuthPopupMutation, + withSetAuthPopupStateMutation, + withShowAuthPopupMutation, +} from "talk-stream/mutations"; +import { Popup } from "talk-ui/components"; + +import UserBox from "../components/UserBox"; + +interface InnerProps { + local: Local; + showAuthPopup: ShowAuthPopupMutation; + setAuthPopupState: SetAuthPopupStateMutation; +} + +class UserBoxContainer extends Component { + private handleFocus = () => this.props.setAuthPopupState({ focus: true }); + private handleBlur = () => this.props.setAuthPopupState({ focus: false }); + private handleClose = () => this.props.setAuthPopupState({ open: false }); + private handleSignIn = () => this.props.showAuthPopup({ view: "SIGN_IN" }); + private handleRegister = () => this.props.showAuthPopup({ view: "SIGN_UP" }); + + public render() { + const { + local: { + authPopup: { open, focus, view }, + }, + } = this.props; + return ( + <> + + + + ); + } +} + +const enhanced = withSetAuthPopupStateMutation( + withShowAuthPopupMutation( + withLocalStateContainer( + graphql` + fragment UserBoxContainerLocal on Local { + authPopup { + open + focus + view + } + } + ` + )(UserBoxContainer) + ) +); + +export default enhanced; diff --git a/src/core/client/stream/local/constants.ts b/src/core/client/stream/local/constants.ts index 599c79497..d4f4bd473 100644 --- a/src/core/client/stream/local/constants.ts +++ b/src/core/client/stream/local/constants.ts @@ -4,3 +4,6 @@ export const NETWORK_TYPE = "Network"; export const NETWORK_ID = "client:root.local.network"; + +export const AUTH_POPUP_TYPE = "AuthPopup"; +export const AUTH_POPUP_ID = "client:root.local.authPopup"; diff --git a/src/core/client/stream/local/initLocalState.ts b/src/core/client/stream/local/initLocalState.ts index 434c60e32..827e90c50 100644 --- a/src/core/client/stream/local/initLocalState.ts +++ b/src/core/client/stream/local/initLocalState.ts @@ -7,7 +7,12 @@ import { LOCAL_TYPE, } from "talk-framework/lib/relay"; -import { NETWORK_ID, NETWORK_TYPE } from "./constants"; +import { + AUTH_POPUP_ID, + AUTH_POPUP_TYPE, + NETWORK_ID, + NETWORK_TYPE, +} from "./constants"; /** * Initializes the local state, before we start the App. @@ -18,6 +23,7 @@ export default async function initLocalState(environment: Environment) { // Create the Local Record which is the Root for the client states. const localRecord = createAndRetain(environment, s, LOCAL_ID, LOCAL_TYPE); + root.setLinkedRecord(localRecord, "local"); // Parse query params const query = qs.parse(location.search); @@ -47,6 +53,17 @@ export default async function initLocalState(environment: Environment) { ); networkRecord.setValue(false, "isOffline"); localRecord.setLinkedRecord(networkRecord, "network"); - root.setLinkedRecord(localRecord, "local"); + + // Create authPopup Record + const authPopupRecord = createAndRetain( + environment, + s, + AUTH_POPUP_ID, + AUTH_POPUP_TYPE + ); + authPopupRecord.setValue(false, "open"); + authPopupRecord.setValue(false, "focus"); + authPopupRecord.setValue("", "href"); + localRecord.setLinkedRecord(authPopupRecord, "authPopup"); }); } diff --git a/src/core/client/stream/local/local.graphql b/src/core/client/stream/local/local.graphql index 9a2991607..52604d35b 100644 --- a/src/core/client/stream/local/local.graphql +++ b/src/core/client/stream/local/local.graphql @@ -3,11 +3,24 @@ type Network { isOffline: Boolean! } +enum View { + SIGN_UP + SIGN_IN + FORGOT_PASSWORD +} + +type AuthPopup { + open: Boolean! + focus: Boolean! + view: View +} + type Local { network: Network! assetID: String - commentID: String assetURL: String + commentID: String + authPopup: AuthPopup! } extend type Query { diff --git a/src/core/client/stream/mutations/SetAuthPopupStateMutation.spec.ts b/src/core/client/stream/mutations/SetAuthPopupStateMutation.spec.ts new file mode 100644 index 000000000..2e03b736c --- /dev/null +++ b/src/core/client/stream/mutations/SetAuthPopupStateMutation.spec.ts @@ -0,0 +1,52 @@ +import { Environment, RecordSource } from "relay-runtime"; + +import { createRelayEnvironment } from "talk-framework/testHelpers"; + +import { AUTH_POPUP_ID, AUTH_POPUP_TYPE } from "../local"; +import { commit } from "./SetAuthPopupStateMutation"; + +let environment: Environment; +const source: RecordSource = new RecordSource(); + +beforeAll(() => { + environment = createRelayEnvironment({ + source, + initLocalState: (localRecord, sourceProxy) => { + const record = sourceProxy.create(AUTH_POPUP_ID, AUTH_POPUP_TYPE); + record.setValue(false, "open"); + record.setValue(false, "focus"); + localRecord.setLinkedRecord(record, "authPopup"); + }, + }); +}); + +it("sets state", () => { + commit(environment, { open: true, focus: false }); + expect(source.get(AUTH_POPUP_ID)!.open).toEqual(true); + expect(source.get(AUTH_POPUP_ID)!.focus).toEqual(false); +}); + +it("sets state", () => { + commit(environment, { + open: false, + focus: true, + href: "https://coralproject.net", + }); + expect(source.get(AUTH_POPUP_ID)!.open).toEqual(false); + expect(source.get(AUTH_POPUP_ID)!.focus).toEqual(true); + expect(source.get(AUTH_POPUP_ID)!.href).toEqual("https://coralproject.net"); +}); + +it("keep previous state", () => { + commit(environment, { open: false, focus: true }); + commit(environment, {}); + expect(source.get(AUTH_POPUP_ID)!.open).toEqual(false); + expect(source.get(AUTH_POPUP_ID)!.focus).toEqual(true); +}); + +it("change only one", () => { + commit(environment, { open: false, focus: true }); + commit(environment, { open: true }); + expect(source.get(AUTH_POPUP_ID)!.open).toEqual(true); + expect(source.get(AUTH_POPUP_ID)!.focus).toEqual(true); +}); diff --git a/src/core/client/stream/mutations/SetAuthPopupStateMutation.ts b/src/core/client/stream/mutations/SetAuthPopupStateMutation.ts new file mode 100644 index 000000000..f3984a69a --- /dev/null +++ b/src/core/client/stream/mutations/SetAuthPopupStateMutation.ts @@ -0,0 +1,38 @@ +import { commitLocalUpdate, Environment } from "relay-runtime"; + +import { createMutationContainer } from "talk-framework/lib/relay"; + +import { AUTH_POPUP_ID } from "../local"; + +export interface SetAuthPopupStateInput { + open?: boolean; + focus?: boolean; + href?: string; +} + +export type SetAuthPopupStateMutation = ( + input: SetAuthPopupStateInput +) => Promise; + +export async function commit( + environment: Environment, + input: SetAuthPopupStateInput +) { + return commitLocalUpdate(environment, store => { + const record = store.get(AUTH_POPUP_ID)!; + if (input.open !== undefined) { + record.setValue(input.open, "open"); + } + if (input.focus !== undefined) { + record.setValue(input.focus, "focus"); + } + if (input.href !== undefined) { + record.setValue(input.href, "href"); + } + }); +} + +export const withSetAuthPopupStateMutation = createMutationContainer( + "setAuthPopupState", + commit +); diff --git a/src/core/client/stream/mutations/SetNetworkStatusMutation.spec.ts b/src/core/client/stream/mutations/SetNetworkStatusMutation.spec.ts index 1a6196c45..2ca97bea9 100644 --- a/src/core/client/stream/mutations/SetNetworkStatusMutation.spec.ts +++ b/src/core/client/stream/mutations/SetNetworkStatusMutation.spec.ts @@ -3,7 +3,6 @@ import { Environment, RecordSource } from "relay-runtime"; import { createRelayEnvironment } from "talk-framework/testHelpers"; import { NETWORK_ID, NETWORK_TYPE } from "../local"; - import { commit } from "./SetNetworkStatusMutation"; let environment: Environment; diff --git a/src/core/client/stream/mutations/ShowAuthPopupMutation.spec.ts b/src/core/client/stream/mutations/ShowAuthPopupMutation.spec.ts new file mode 100644 index 000000000..17d612d89 --- /dev/null +++ b/src/core/client/stream/mutations/ShowAuthPopupMutation.spec.ts @@ -0,0 +1,42 @@ +import { Environment, RecordSource } from "relay-runtime"; + +import { createRelayEnvironment } from "talk-framework/testHelpers"; + +import { AUTH_POPUP_ID, AUTH_POPUP_TYPE } from "../local"; +import { commit } from "./ShowAuthPopupMutation"; + +let environment: Environment; +const source: RecordSource = new RecordSource(); + +beforeAll(() => { + environment = createRelayEnvironment({ + source, + initLocalState: (localRecord, sourceProxy) => { + const record = sourceProxy.create(AUTH_POPUP_ID, AUTH_POPUP_TYPE); + record.setValue(false, "open"); + record.setValue(false, "focus"); + localRecord.setLinkedRecord(record, "authPopup"); + }, + }); +}); + +it("opens popup", () => { + commit(environment, { view: "SIGN_IN" }); + expect(source.get(AUTH_POPUP_ID)!.open).toEqual(true); + expect(source.get(AUTH_POPUP_ID)!.focus).toEqual(false); + expect(source.get(AUTH_POPUP_ID)!.view).toEqual("SIGN_IN"); +}); + +it("focuses popup", () => { + commit(environment, { view: "SIGN_IN" }); + expect(source.get(AUTH_POPUP_ID)!.open).toEqual(true); + expect(source.get(AUTH_POPUP_ID)!.focus).toEqual(true); + expect(source.get(AUTH_POPUP_ID)!.view).toEqual("SIGN_IN"); +}); + +it("only change view when opened and focused", () => { + commit(environment, { view: "FORGOT_PASSWORD" }); + expect(source.get(AUTH_POPUP_ID)!.open).toEqual(true); + expect(source.get(AUTH_POPUP_ID)!.focus).toEqual(true); + expect(source.get(AUTH_POPUP_ID)!.view).toEqual("FORGOT_PASSWORD"); +}); diff --git a/src/core/client/stream/mutations/ShowAuthPopupMutation.ts b/src/core/client/stream/mutations/ShowAuthPopupMutation.ts new file mode 100644 index 000000000..2d6936d53 --- /dev/null +++ b/src/core/client/stream/mutations/ShowAuthPopupMutation.ts @@ -0,0 +1,36 @@ +import { commitLocalUpdate, Environment } from "relay-runtime"; + +import { createMutationContainer } from "talk-framework/lib/relay"; + +import { AUTH_POPUP_ID } from "../local"; + +export interface ShowAuthPopupInput { + view: "SIGN_IN" | "SIGN_UP" | "FORGOT_PASSWORD"; +} + +export type ShowAuthPopupMutation = ( + input: ShowAuthPopupInput +) => Promise; + +export async function commit( + environment: Environment, + input: ShowAuthPopupInput +) { + return commitLocalUpdate(environment, store => { + const record = store.get(AUTH_POPUP_ID)!; + record.setValue(input.view, "view"); + if (!record.getValue("open")) { + record.setValue(true, "open"); + return; + } + if (!record.getValue("focus")) { + record.setValue(true, "focus"); + return; + } + }); +} + +export const withShowAuthPopupMutation = createMutationContainer( + "showAuthPopup", + commit +); diff --git a/src/core/client/stream/mutations/index.ts b/src/core/client/stream/mutations/index.ts index 1b71335e7..324fddbdc 100644 --- a/src/core/client/stream/mutations/index.ts +++ b/src/core/client/stream/mutations/index.ts @@ -13,3 +13,11 @@ export { SetCommentIDMutation, SetCommentIDInput, } from "./SetCommentIDMutation"; +export { + withShowAuthPopupMutation, + ShowAuthPopupMutation, +} from "./ShowAuthPopupMutation"; +export { + withSetAuthPopupStateMutation, + SetAuthPopupStateMutation, +} from "./SetAuthPopupStateMutation"; diff --git a/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap index 619f3269d..95be74360 100644 --- a/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap +++ b/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap @@ -5,10 +5,49 @@ exports[`loads more comments 1`] = ` className="Flex-root App-root Flex-justifyCenter Flex-alignCenter" >
+
+ + Join the conversation + + + | + + + +
@@ -148,10 +187,49 @@ exports[`renders comment stream 1`] = ` className="Flex-root App-root Flex-justifyCenter Flex-alignCenter" >
+
+ + Join the conversation + + + | + + + +
diff --git a/src/core/client/stream/test/__snapshots__/permalinkView.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/permalinkView.spec.tsx.snap index 8c5b5b287..f0a7e2dc0 100644 --- a/src/core/client/stream/test/__snapshots__/permalinkView.spec.tsx.snap +++ b/src/core/client/stream/test/__snapshots__/permalinkView.spec.tsx.snap @@ -61,10 +61,49 @@ exports[`show all comments 1`] = ` className="Flex-root App-root Flex-justifyCenter Flex-alignCenter" >
+
+ + Join the conversation + + + | + + + +
diff --git a/src/core/client/stream/test/__snapshots__/permalinkViewCommentNotFound.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/permalinkViewCommentNotFound.spec.tsx.snap index 6e094cf1e..86c327dd8 100644 --- a/src/core/client/stream/test/__snapshots__/permalinkViewCommentNotFound.spec.tsx.snap +++ b/src/core/client/stream/test/__snapshots__/permalinkViewCommentNotFound.spec.tsx.snap @@ -34,10 +34,49 @@ exports[`show all comments 1`] = ` className="Flex-root App-root Flex-justifyCenter Flex-alignCenter" >
+
+ + Join the conversation + + + | + + + +
diff --git a/src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap index ef93886d2..a778e60c1 100644 --- a/src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap +++ b/src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap @@ -5,10 +5,49 @@ exports[`renders comment stream 1`] = ` className="Flex-root App-root Flex-justifyCenter Flex-alignCenter" >
+
+ + Join the conversation + + + | + + + +
diff --git a/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap index e026b3372..6bc43f944 100644 --- a/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap +++ b/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap @@ -5,10 +5,49 @@ exports[`renders comment stream 1`] = ` className="Flex-root App-root Flex-justifyCenter Flex-alignCenter" >
+
+ + Join the conversation + + + | + + + +
diff --git a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap index dac444642..846fcfdec 100644 --- a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap +++ b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap @@ -5,10 +5,49 @@ exports[`renders comment stream 1`] = ` className="Flex-root App-root Flex-justifyCenter Flex-alignCenter" >
+
+ + Join the conversation + + + | + + + +
@@ -137,10 +176,49 @@ exports[`show all replies 1`] = ` className="Flex-root App-root Flex-justifyCenter Flex-alignCenter" >
+
+ + Join the conversation + + + | + + + +
diff --git a/src/core/client/stream/test/createEnvironment.ts b/src/core/client/stream/test/createEnvironment.ts new file mode 100644 index 000000000..1a7fb7710 --- /dev/null +++ b/src/core/client/stream/test/createEnvironment.ts @@ -0,0 +1,34 @@ +import { IResolvers } from "graphql-tools"; +import { Environment, RecordProxy, RecordSourceProxy } from "relay-runtime"; +import { createRelayEnvironment } from "talk-framework/testHelpers"; +import { AUTH_POPUP_ID, AUTH_POPUP_TYPE } from "talk-stream/local"; + +interface CreateEnvironmentParams { + logNetwork?: boolean; + resolvers: IResolvers; + initLocalState?: ( + local: RecordProxy, + source: RecordSourceProxy, + environment: Environment + ) => void; +} + +export default function createEnvironment(params: CreateEnvironmentParams) { + return createRelayEnvironment({ + network: { + logNetwork: params.logNetwork, + resolvers: params.resolvers, + projectName: "tenant", + }, + initLocalState: (localRecord, source, environment) => { + const authPopupRecord = source.create(AUTH_POPUP_ID, AUTH_POPUP_TYPE); + authPopupRecord.setValue(false, "open"); + authPopupRecord.setValue(false, "focus"); + authPopupRecord.setValue("", "href"); + localRecord.setLinkedRecord(authPopupRecord, "authPopup"); + if (params.initLocalState) { + params.initLocalState(localRecord, source, environment); + } + }, + }); +} diff --git a/src/core/client/stream/test/loadMore.spec.tsx b/src/core/client/stream/test/loadMore.spec.tsx index 0f2c1642d..afe07b39f 100644 --- a/src/core/client/stream/test/loadMore.spec.tsx +++ b/src/core/client/stream/test/loadMore.spec.tsx @@ -1,13 +1,12 @@ import React from "react"; import TestRenderer from "react-test-renderer"; -import { RecordProxy } from "relay-runtime"; import sinon from "sinon"; import { timeout } from "talk-common/utils"; import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap"; -import { createRelayEnvironment } from "talk-framework/testHelpers"; import AppContainer from "talk-stream/containers/AppContainer"; +import createEnvironment from "./createEnvironment"; import { assets, comments } from "./fixtures"; const connectionStub = sinon.stub().throws(); @@ -61,14 +60,11 @@ const resolvers = { }, }; -const environment = createRelayEnvironment({ - network: { - // Set this to true, to see graphql responses. - logNetwork: false, - resolvers, - projectName: "tenant", - }, - initLocalState: (localRecord: RecordProxy) => { +const environment = createEnvironment({ + // Set this to true, to see graphql responses. + logNetwork: false, + resolvers, + initLocalState: (localRecord, source) => { localRecord.setValue(assetStub.id, "assetID"); }, }); diff --git a/src/core/client/stream/test/permalinkView.spec.tsx b/src/core/client/stream/test/permalinkView.spec.tsx index 09b0c05fe..c056ef4aa 100644 --- a/src/core/client/stream/test/permalinkView.spec.tsx +++ b/src/core/client/stream/test/permalinkView.spec.tsx @@ -5,9 +5,9 @@ import sinon from "sinon"; import { timeout } from "talk-common/utils"; import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap"; -import { createRelayEnvironment } from "talk-framework/testHelpers"; import AppContainer from "talk-stream/containers/AppContainer"; +import createEnvironment from "./createEnvironment"; import { assets, comments } from "./fixtures"; const commentStub = { @@ -44,13 +44,10 @@ const resolvers = { }, }; -const environment = createRelayEnvironment({ - network: { - // Set this to true, to see graphql responses. - logNetwork: false, - resolvers, - projectName: "tenant", - }, +const environment = createEnvironment({ + // Set this to true, to see graphql responses. + logNetwork: false, + resolvers, initLocalState: (localRecord: RecordProxy) => { localRecord.setValue(assetStub.id, "assetID"); localRecord.setValue(commentStub.id, "commentID"); diff --git a/src/core/client/stream/test/permalinkViewAssetNotFound.spec.tsx b/src/core/client/stream/test/permalinkViewAssetNotFound.spec.tsx index 4ee8ebb5c..17be1416e 100644 --- a/src/core/client/stream/test/permalinkViewAssetNotFound.spec.tsx +++ b/src/core/client/stream/test/permalinkViewAssetNotFound.spec.tsx @@ -4,9 +4,10 @@ import { RecordProxy } from "relay-runtime"; import { timeout } from "talk-common/utils"; import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap"; -import { createRelayEnvironment } from "talk-framework/testHelpers"; import AppContainer from "talk-stream/containers/AppContainer"; +import createEnvironment from "./createEnvironment"; + const resolvers = { Query: { comment: () => null, @@ -14,13 +15,10 @@ const resolvers = { }, }; -const environment = createRelayEnvironment({ - network: { - // Set this to true, to see graphql responses. - logNetwork: false, - resolvers, - projectName: "tenant", - }, +const environment = createEnvironment({ + // Set this to true, to see graphql responses. + logNetwork: false, + resolvers, initLocalState: (localRecord: RecordProxy) => { localRecord.setValue("unknown-asset-id", "assetID"); localRecord.setValue("unknown-comment-id", "commentID"); diff --git a/src/core/client/stream/test/permalinkViewCommentNotFound.spec.tsx b/src/core/client/stream/test/permalinkViewCommentNotFound.spec.tsx index 473e6d510..3f905ce4b 100644 --- a/src/core/client/stream/test/permalinkViewCommentNotFound.spec.tsx +++ b/src/core/client/stream/test/permalinkViewCommentNotFound.spec.tsx @@ -5,9 +5,9 @@ import sinon from "sinon"; import { timeout } from "talk-common/utils"; import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap"; -import { createRelayEnvironment } from "talk-framework/testHelpers"; import AppContainer from "talk-stream/containers/AppContainer"; +import createEnvironment from "./createEnvironment"; import { assets, comments } from "./fixtures"; const commentStub = { @@ -40,13 +40,10 @@ const resolvers = { }, }; -const environment = createRelayEnvironment({ - network: { - // Set this to true, to see graphql responses. - logNetwork: false, - resolvers, - projectName: "tenant", - }, +const environment = createEnvironment({ + // Set this to true, to see graphql responses. + logNetwork: false, + resolvers, initLocalState: (localRecord: RecordProxy) => { localRecord.setValue(assetStub.id, "assetID"); localRecord.setValue("unknown-comment-id", "commentID"); diff --git a/src/core/client/stream/test/renderReplies.spec.tsx b/src/core/client/stream/test/renderReplies.spec.tsx index 221dc19c0..468317624 100644 --- a/src/core/client/stream/test/renderReplies.spec.tsx +++ b/src/core/client/stream/test/renderReplies.spec.tsx @@ -5,9 +5,9 @@ import sinon from "sinon"; import { timeout } from "talk-common/utils"; import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap"; -import { createRelayEnvironment } from "talk-framework/testHelpers"; import AppContainer from "talk-stream/containers/AppContainer"; +import createEnvironment from "./createEnvironment"; import { assetWithReplies } from "./fixtures"; const resolvers = { @@ -20,13 +20,10 @@ const resolvers = { }, }; -const environment = createRelayEnvironment({ - network: { - // Set this to true, to see graphql responses. - logNetwork: false, - resolvers, - projectName: "tenant", - }, +const environment = createEnvironment({ + // Set this to true, to see graphql responses. + logNetwork: false, + resolvers, initLocalState: (localRecord: RecordProxy) => { localRecord.setValue(assetWithReplies.id, "assetID"); }, diff --git a/src/core/client/stream/test/renderStream.spec.tsx b/src/core/client/stream/test/renderStream.spec.tsx index 3c31c1080..361f6e2c2 100644 --- a/src/core/client/stream/test/renderStream.spec.tsx +++ b/src/core/client/stream/test/renderStream.spec.tsx @@ -5,9 +5,9 @@ import sinon from "sinon"; import { timeout } from "talk-common/utils"; import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap"; -import { createRelayEnvironment } from "talk-framework/testHelpers"; import AppContainer from "talk-stream/containers/AppContainer"; +import createEnvironment from "./createEnvironment"; import { assets } from "./fixtures"; const resolvers = { @@ -20,13 +20,10 @@ const resolvers = { }, }; -const environment = createRelayEnvironment({ - network: { - // Set this to true, to see graphql responses. - logNetwork: false, - resolvers, - projectName: "tenant", - }, +const environment = createEnvironment({ + // Set this to true, to see graphql responses. + logNetwork: false, + resolvers, initLocalState: (localRecord: RecordProxy) => { localRecord.setValue(assets[0].id, "assetID"); }, diff --git a/src/core/client/stream/test/showAllReplies.spec.tsx b/src/core/client/stream/test/showAllReplies.spec.tsx index 71f857331..7bf111990 100644 --- a/src/core/client/stream/test/showAllReplies.spec.tsx +++ b/src/core/client/stream/test/showAllReplies.spec.tsx @@ -5,9 +5,9 @@ import sinon from "sinon"; import { timeout } from "talk-common/utils"; import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap"; -import { createRelayEnvironment } from "talk-framework/testHelpers"; import AppContainer from "talk-stream/containers/AppContainer"; +import createEnvironment from "./createEnvironment"; import { assets, comments } from "./fixtures"; const connectionStub = sinon.stub().throws(); @@ -77,13 +77,10 @@ const resolvers = { }, }; -const environment = createRelayEnvironment({ - network: { - // Set this to true, to see graphql responses. - logNetwork: false, - resolvers, - projectName: "tenant", - }, +const environment = createEnvironment({ + // Set this to true, to see graphql responses. + logNetwork: false, + resolvers, initLocalState: (localRecord: RecordProxy) => { localRecord.setValue(assetStub.id, "assetID"); }, diff --git a/src/core/client/ui/components/Button/Button.css b/src/core/client/ui/components/Button/Button.css index 3a0151ecc..9345a33b6 100644 --- a/src/core/client/ui/components/Button/Button.css +++ b/src/core/client/ui/components/Button/Button.css @@ -6,7 +6,7 @@ justify-content: center; align-items: center; box-sizing: border-box; - border: 1px solid transparent; + border: 0px solid transparent; & > * { margin: 0 calc(0.5 * var(--spacing-unit)) 0 0; @@ -154,6 +154,7 @@ } .variantOutlined { + border: 1px solid transparent; &.colorRegular { color: var(--palette-grey-main); border: 1px solid currentColor; @@ -220,6 +221,7 @@ } .variantGhost { + border: 1px solid transparent; &.colorRegular { color: var(--palette-grey-main); } diff --git a/src/core/client/ui/components/Flex/Flex.css b/src/core/client/ui/components/Flex/Flex.css index 9b5b9a6e9..c154df97a 100644 --- a/src/core/client/ui/components/Flex/Flex.css +++ b/src/core/client/ui/components/Flex/Flex.css @@ -1,8 +1,5 @@ .root { display: flex; - & > * { - flex-shrink: 0; - } } .halfItemGutter { diff --git a/src/core/client/ui/components/Flex/Flex.tsx b/src/core/client/ui/components/Flex/Flex.tsx index 4a5abbc08..d43c567eb 100644 --- a/src/core/client/ui/components/Flex/Flex.tsx +++ b/src/core/client/ui/components/Flex/Flex.tsx @@ -80,6 +80,10 @@ const Flex: StatelessComponent = props => { return
; }; +Flex.defaultProps = { + wrap: true, +}; + const enhanced = withForwardRef(withStyles(styles)(Flex)); export default enhanced; export type FlexProps = PropTypesOf; diff --git a/src/core/client/ui/components/Popup/Popup.ts b/src/core/client/ui/components/Popup/Popup.ts index a39c985f9..b362d86d1 100644 --- a/src/core/client/ui/components/Popup/Popup.ts +++ b/src/core/client/ui/components/Popup/Popup.ts @@ -36,6 +36,9 @@ export default class Popup extends Component { } private setCallbacks() { + if (!this.ref) { + return; + } this.ref!.onload = e => { if (this.detectCloseInterval) { clearInterval(this.detectCloseInterval); diff --git a/src/core/client/ui/components/Typography/Typography.css b/src/core/client/ui/components/Typography/Typography.css index 8b0edc3b8..9f2a5b699 100644 --- a/src/core/client/ui/components/Typography/Typography.css +++ b/src/core/client/ui/components/Typography/Typography.css @@ -23,6 +23,10 @@ composes: bodyCopy from "talk-ui/shared/typography.css"; } +.bodyCopyBold { + composes: bodyCopyBold from "talk-ui/shared/typography.css"; +} + .button { composes: button from "talk-ui/shared/typography.css"; } diff --git a/src/core/client/ui/components/Typography/Typography.mdx b/src/core/client/ui/components/Typography/Typography.mdx index 8833e95f9..f30f8e6c2 100644 --- a/src/core/client/ui/components/Typography/Typography.mdx +++ b/src/core/client/ui/components/Typography/Typography.mdx @@ -17,6 +17,7 @@ import Flex from '../Flex' Heading3 Heading4 BodyCopy + bodyCopyBold timestamp diff --git a/src/core/client/ui/components/Typography/Typography.tsx b/src/core/client/ui/components/Typography/Typography.tsx index 752f1f828..a4ab393cc 100644 --- a/src/core/client/ui/components/Typography/Typography.tsx +++ b/src/core/client/ui/components/Typography/Typography.tsx @@ -13,6 +13,7 @@ type Variant = | "heading3" | "heading4" | "bodyCopy" + | "bodyCopyBold" | "timestamp"; // Based on Typography Component of Material UI. @@ -130,6 +131,7 @@ Typography.defaultProps = { heading3: "h1", heading4: "h1", bodyCopy: "p", + bodyCopyBold: "p", timestamp: "span", }, noWrap: false, diff --git a/src/core/client/ui/shared/typography.css b/src/core/client/ui/shared/typography.css index 518d0561f..c81577465 100644 --- a/src/core/client/ui/shared/typography.css +++ b/src/core/client/ui/shared/typography.css @@ -100,6 +100,11 @@ color: var(--palette-text-primary); } +.bodyCopyBold { + composes: bodyCopy; + font-weight: var(--font-weight-medium); +} + .button { color: var(--palette-text-secondary); font-family: "Source Sans Pro"; diff --git a/src/core/server/graph/tenant/schema/schema.graphql b/src/core/server/graph/tenant/schema/schema.graphql index b045c572f..302b9e525 100644 --- a/src/core/server/graph/tenant/schema/schema.graphql +++ b/src/core/server/graph/tenant/schema/schema.graphql @@ -774,7 +774,8 @@ type Mutation { """ updateSettings will update the Settings for the given Tenant. """ - updateSettings(input: UpdateSettingsInput!): UpdateSettingsPayload @auth(roles: [ADMIN]) + updateSettings(input: UpdateSettingsInput!): UpdateSettingsPayload + @auth(roles: [ADMIN]) } ################################################################################