From 05296d4802b32dacfc1944649dcf0773bb1617b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Curcio?= Date: Fri, 14 Sep 2018 10:03:25 -0300 Subject: [PATCH 01/35] Adding tabs to the stream <3 --- src/core/client/stream/components/App.tsx | 31 ++++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/core/client/stream/components/App.tsx b/src/core/client/stream/components/App.tsx index 421e6af9c..8e9dcc437 100644 --- a/src/core/client/stream/components/App.tsx +++ b/src/core/client/stream/components/App.tsx @@ -1,7 +1,13 @@ import * as React from "react"; import { StatelessComponent } from "react"; -import { Flex } from "talk-ui/components"; +import { + HorizontalGutter, + Tab, + TabBar, + TabContent, + TabPane, +} from "talk-ui/components"; import CommentsPaneContainer from "../tabs/comments/containers/CommentsPaneContainer"; import * as styles from "./App.css"; @@ -11,18 +17,19 @@ export interface AppProps { } const App: StatelessComponent = props => { - let view: React.ReactElement; - switch (props.activeTab) { - case "COMMENTS": - view = ; - break; - default: - throw new Error(`Unknown tab ${props.activeTab}`); - } return ( - - {view} - + + + Comments + My Profile + + + + + + My profileeeeee + + ); }; From 1009045c4c7ad758c188872fb730719bbb15603c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Curcio?= Date: Fri, 14 Sep 2018 10:13:42 -0300 Subject: [PATCH 02/35] Working tabs --- src/core/client/stream/components/App.tsx | 10 +- .../client/stream/containers/AppContainer.tsx | 10 +- .../stream/mutations/SetActiveTabMutation.ts | 2 +- .../__snapshots__/editComment.spec.tsx.snap | 401 ++++++++++++++++++ 4 files changed, 418 insertions(+), 5 deletions(-) diff --git a/src/core/client/stream/components/App.tsx b/src/core/client/stream/components/App.tsx index 8e9dcc437..b45756b46 100644 --- a/src/core/client/stream/components/App.tsx +++ b/src/core/client/stream/components/App.tsx @@ -9,17 +9,23 @@ import { TabPane, } from "talk-ui/components"; +import { SetActiveTabMutation } from "talk-stream/mutations"; + import CommentsPaneContainer from "../tabs/comments/containers/CommentsPaneContainer"; import * as styles from "./App.css"; export interface AppProps { - activeTab: "COMMENTS" | "%future added value"; + activeTab: "COMMENTS" | "PROFILE" | "%future added value"; + setActiveTab: SetActiveTabMutation; } const App: StatelessComponent = props => { return ( - + props.setActiveTab({ tab })} + > Comments My Profile diff --git a/src/core/client/stream/containers/AppContainer.tsx b/src/core/client/stream/containers/AppContainer.tsx index 011a0bee8..f9c7d8e53 100644 --- a/src/core/client/stream/containers/AppContainer.tsx +++ b/src/core/client/stream/containers/AppContainer.tsx @@ -3,17 +3,23 @@ import { StatelessComponent } from "react"; import { graphql, withLocalStateContainer } from "talk-framework/lib/relay"; import { AppContainerLocal as Local } from "talk-stream/__generated__/AppContainerLocal.graphql"; +import { + SetActiveTabMutation, + withSetActiveTabMutation, +} from "talk-stream/mutations"; import App from "../components/App"; interface InnerProps { local: Local; + setActiveTab: SetActiveTabMutation; } const AppContainer: StatelessComponent = ({ local: { activeTab }, + setActiveTab, }) => { - return ; + return ; }; const enhanced = withLocalStateContainer( @@ -22,6 +28,6 @@ const enhanced = withLocalStateContainer( activeTab } ` -)(AppContainer); +)(withSetActiveTabMutation(AppContainer)); export default enhanced; diff --git a/src/core/client/stream/mutations/SetActiveTabMutation.ts b/src/core/client/stream/mutations/SetActiveTabMutation.ts index 8c930dd0c..8cffe9828 100644 --- a/src/core/client/stream/mutations/SetActiveTabMutation.ts +++ b/src/core/client/stream/mutations/SetActiveTabMutation.ts @@ -3,7 +3,7 @@ import { commitLocalUpdate, Environment } from "relay-runtime"; import { createMutationContainer, LOCAL_ID } from "talk-framework/lib/relay"; export interface SetActiveTabInput { - tab: "COMMENTS"; + tab: "COMMENTS" | "PROFILE" | string; } export type SetActiveTabMutation = (input: SetActiveTabInput) => Promise; diff --git a/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap index 6a91b49e0..89fa7f723 100644 --- a/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap @@ -335,6 +335,407 @@ exports[`cancel edit: edit canceled 1`] = ` `; +exports[`cancel edit: server response 1`] = ` +
+
    + + +
+
+
+
+
+
+
+ Signed in as + + Markus + + . +
+
+ + Not you?  + + +
+
+
+
+
+
+ +
+
+
+ + + +
+ +
+
+
+
+
+
+ + Powered by + + ⁨The Coral Project⁩ + + +
+ +
+
+ +
+
+
+
+
+
+
+ + Markus + +
+ +
+ ( + + Edited + + ) +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+
+
+
+ + Lukas + +
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+`; + exports[`edit a comment: edit form 1`] = `
Date: Fri, 14 Sep 2018 10:43:40 -0300 Subject: [PATCH 03/35] WIP --- src/core/client/stream/components/App.tsx | 5 ++- .../tabs/profile/components/Profile.tsx | 21 ++++++++++ .../profile/containers/ProfileContainer.tsx | 26 ++++++++++++ .../tabs/profile/queries/ProfileQuery.tsx | 40 +++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/core/client/stream/tabs/profile/components/Profile.tsx create mode 100644 src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx create mode 100644 src/core/client/stream/tabs/profile/queries/ProfileQuery.tsx diff --git a/src/core/client/stream/components/App.tsx b/src/core/client/stream/components/App.tsx index b45756b46..d78881430 100644 --- a/src/core/client/stream/components/App.tsx +++ b/src/core/client/stream/components/App.tsx @@ -12,6 +12,7 @@ import { import { SetActiveTabMutation } from "talk-stream/mutations"; import CommentsPaneContainer from "../tabs/comments/containers/CommentsPaneContainer"; +import ProfileContainer from "../tabs/profile/containers/ProfileContainer"; import * as styles from "./App.css"; export interface AppProps { @@ -33,7 +34,9 @@ const App: StatelessComponent = props => { - My profileeeeee + + + ); diff --git a/src/core/client/stream/tabs/profile/components/Profile.tsx b/src/core/client/stream/tabs/profile/components/Profile.tsx new file mode 100644 index 000000000..b8223f70d --- /dev/null +++ b/src/core/client/stream/tabs/profile/components/Profile.tsx @@ -0,0 +1,21 @@ +import * as React from "react"; +import { StatelessComponent } from "react"; +import { PropTypesOf } from "talk-framework/types"; +import UserBoxContainer from "talk-stream/containers/UserBoxContainer"; +import { HorizontalGutter } from "talk-ui/components"; + +export interface ProfileProps { + me: PropTypesOf["me"] | null; +} + +const Profile: StatelessComponent = props => { + return ( + + + + + + ); +}; + +export default Profile; diff --git a/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx b/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx new file mode 100644 index 000000000..50570f913 --- /dev/null +++ b/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { graphql } from "react-relay"; + +import { withFragmentContainer } from "talk-framework/lib/relay"; +import { ProfileContainer_me as MeData } from "talk-stream/__generated__/ProfileContainer_me.graphql"; + +import Profile from "../components/Profile"; + +interface ProfileContainerProps { + me: MeData | null; +} + +export class StreamContainer extends React.Component { + public render() { + return ; + } +} +const enhanced = withFragmentContainer({ + me: graphql` + fragment ProfileContainer_me on User { + ...UserBoxContainer_me + } + `, +})(StreamContainer); + +export default enhanced; diff --git a/src/core/client/stream/tabs/profile/queries/ProfileQuery.tsx b/src/core/client/stream/tabs/profile/queries/ProfileQuery.tsx new file mode 100644 index 000000000..7662343e1 --- /dev/null +++ b/src/core/client/stream/tabs/profile/queries/ProfileQuery.tsx @@ -0,0 +1,40 @@ +import React, { StatelessComponent } from "react"; +import { ReadyState } from "react-relay"; +import { graphql, QueryRenderer } from "talk-framework/lib/relay"; +import { ProfileQuery as QueryTypes } from "talk-stream/__generated__/ProfileQuery.graphql"; +import { Spinner } from "talk-ui/components"; +import ProfileContainer from "../containers/ProfileContainer"; + +export const render = ({ + error, + props, +}: ReadyState) => { + if (error) { + return
{error.message}
; + } + + if (props) { + if (!props.me) { + return
Error loading profile
; + } + return ; + } + + return ; +}; + +const ProfileQuery: StatelessComponent = () => ( + + query={graphql` + query ProfileQuery { + me { + ...ProfileContainer_me + } + } + `} + variables={{}} + render={render} + /> +); + +export default ProfileQuery; From 60d61d40b63050a3e853019e7c38fa6d4569bc28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Curcio?= Date: Fri, 14 Sep 2018 11:35:01 -0300 Subject: [PATCH 04/35] Comment History --- src/core/client/stream/components/App.tsx | 4 +-- .../profile/components/CommentHistory.tsx | 14 ++++++++ .../tabs/profile/components/Profile.tsx | 7 +++- .../containers/CommentHistoryContainer.tsx | 35 +++++++++++++++++++ .../profile/containers/ProfileContainer.tsx | 6 +++- .../server/graph/tenant/schema/schema.graphql | 11 +++++- 6 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 src/core/client/stream/tabs/profile/components/CommentHistory.tsx create mode 100644 src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx diff --git a/src/core/client/stream/components/App.tsx b/src/core/client/stream/components/App.tsx index d78881430..faaad4fa4 100644 --- a/src/core/client/stream/components/App.tsx +++ b/src/core/client/stream/components/App.tsx @@ -12,7 +12,7 @@ import { import { SetActiveTabMutation } from "talk-stream/mutations"; import CommentsPaneContainer from "../tabs/comments/containers/CommentsPaneContainer"; -import ProfileContainer from "../tabs/profile/containers/ProfileContainer"; +import ProfileQuery from "../tabs/profile/queries/ProfileQuery"; import * as styles from "./App.css"; export interface AppProps { @@ -35,7 +35,7 @@ const App: StatelessComponent = props => { - + diff --git a/src/core/client/stream/tabs/profile/components/CommentHistory.tsx b/src/core/client/stream/tabs/profile/components/CommentHistory.tsx new file mode 100644 index 000000000..b2804adf8 --- /dev/null +++ b/src/core/client/stream/tabs/profile/components/CommentHistory.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; +import { StatelessComponent } from "react"; +import { CommentHistoryContainer_me as MeData } from "talk-stream/__generated__/CommentHistoryContainer_me.graphql"; +import { HorizontalGutter } from "talk-ui/components"; + +export interface CommentHistoryProps { + me: MeData; +} + +const CommentHistory: StatelessComponent = props => { + return Comments; +}; + +export default CommentHistory; diff --git a/src/core/client/stream/tabs/profile/components/Profile.tsx b/src/core/client/stream/tabs/profile/components/Profile.tsx index b8223f70d..516b7ac74 100644 --- a/src/core/client/stream/tabs/profile/components/Profile.tsx +++ b/src/core/client/stream/tabs/profile/components/Profile.tsx @@ -3,9 +3,13 @@ import { StatelessComponent } from "react"; import { PropTypesOf } from "talk-framework/types"; import UserBoxContainer from "talk-stream/containers/UserBoxContainer"; import { HorizontalGutter } from "talk-ui/components"; +import CommentHistoryContainer from "../containers/CommentHistoryContainer"; export interface ProfileProps { - me: PropTypesOf["me"] | null; + me: + | PropTypesOf["me"] & + PropTypesOf["me"] + | null; } const Profile: StatelessComponent = props => { @@ -13,6 +17,7 @@ const Profile: StatelessComponent = props => { + {props.me && } ); diff --git a/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx b/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx new file mode 100644 index 000000000..d46cec7d4 --- /dev/null +++ b/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import { graphql } from "react-relay"; + +import { withFragmentContainer } from "talk-framework/lib/relay"; +import { CommentHistoryContainer_me as CommentsData } from "talk-stream/__generated__/CommentHistoryContainer_me.graphql"; + +import CommentHistory from "../components/CommentHistory"; + +interface CommentHistoryContainerProps { + me: CommentsData; +} + +export class CommentHistoryContainer extends React.Component< + CommentHistoryContainerProps +> { + public render() { + return ; + } +} +const enhanced = withFragmentContainer({ + me: graphql` + fragment CommentHistoryContainer_me on User { + comments { + edges { + node { + id + body + } + } + } + } + `, +})(CommentHistoryContainer); + +export default enhanced; diff --git a/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx b/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx index 50570f913..6ece17835 100644 --- a/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx +++ b/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx @@ -12,13 +12,17 @@ interface ProfileContainerProps { export class StreamContainer extends React.Component { public render() { - return ; + if (this.props.me) { + return ; + } + return null; } } const enhanced = withFragmentContainer({ me: graphql` fragment ProfileContainer_me on User { ...UserBoxContainer_me + ...CommentHistoryContainer_me } `, })(StreamContainer); diff --git a/src/core/server/graph/tenant/schema/schema.graphql b/src/core/server/graph/tenant/schema/schema.graphql index 9b808db0d..e8f4cc42f 100644 --- a/src/core/server/graph/tenant/schema/schema.graphql +++ b/src/core/server/graph/tenant/schema/schema.graphql @@ -5,7 +5,7 @@ """ auth is a directive that will enforce authorization rules on the schema definition. It will restrict the viewer of the field based on roles or if the -`userIDField` is specified, it will see if the current users ID equals the field +`userIDField` is specified, it will see if the current users ID equals the field specified. This allows users that own a specific resource (like a comment, or a flag) see their own content, but restrict it to everyone else. If the directive is used without options, it simply requires a logged in user. @@ -546,6 +546,15 @@ type User { role is the current role of the User. """ role: USER_ROLE! @auth(roles: [ADMIN, MODERATOR], userIDField: "id") + + """ + comments are the comments of the User. + """ + comments( + first: Int = 10 + orderBy: COMMENT_SORT = CREATED_AT_DESC + after: Cursor + ): CommentsConnection! } ################################################################################ From ced45a914ce77563d35e83718ecd2f134dbcbccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Curcio?= Date: Fri, 14 Sep 2018 12:05:19 -0300 Subject: [PATCH 05/35] Comment History Working --- .../server/graph/tenant/loaders/comments.ts | 15 ++++++++++++ src/core/server/graph/tenant/loaders/users.ts | 2 ++ .../server/graph/tenant/resolvers/index.ts | 2 ++ .../server/graph/tenant/resolvers/query.ts | 2 +- .../server/graph/tenant/resolvers/user.ts | 9 +++++++ src/core/server/models/comment.ts | 24 +++++++++++++++++++ 6 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/core/server/graph/tenant/resolvers/user.ts diff --git a/src/core/server/graph/tenant/loaders/comments.ts b/src/core/server/graph/tenant/loaders/comments.ts index 111a40cd4..a77e50894 100644 --- a/src/core/server/graph/tenant/loaders/comments.ts +++ b/src/core/server/graph/tenant/loaders/comments.ts @@ -9,6 +9,7 @@ import { import { retrieveCommentAssetConnection, retrieveCommentRepliesConnection, + retrieveCommentUserConnection, retrieveManyComments, } from "talk-server/models/comment"; @@ -16,6 +17,20 @@ export default (ctx: Context) => ({ comment: new DataLoader((ids: string[]) => retrieveManyComments(ctx.mongo, ctx.tenant.id, ids) ), + forUser: ( + userID: string, + // Apply the graph schema defaults at the loader. + { + first = 10, + orderBy = GQLCOMMENT_SORT.CREATED_AT_DESC, + after, + }: AssetToCommentsArgs + ) => + retrieveCommentUserConnection(ctx.mongo, ctx.tenant.id, userID, { + first, + orderBy, + after, + }), forAsset: ( assetID: string, // Apply the graph schema defaults at the loader. diff --git a/src/core/server/graph/tenant/loaders/users.ts b/src/core/server/graph/tenant/loaders/users.ts index c684a9d23..558981daa 100644 --- a/src/core/server/graph/tenant/loaders/users.ts +++ b/src/core/server/graph/tenant/loaders/users.ts @@ -1,8 +1,10 @@ import DataLoader from "dataloader"; import Context from "talk-server/graph/tenant/context"; +// import { retrieveCommentUserConnection } from "talk-server/models/comment"; import { retrieveManyUsers, User } from "talk-server/models/user"; export default (ctx: Context) => ({ + me: ctx.user, user: new DataLoader(ids => retrieveManyUsers(ctx.mongo, ctx.tenant.id, ids) ), diff --git a/src/core/server/graph/tenant/resolvers/index.ts b/src/core/server/graph/tenant/resolvers/index.ts index f8754d04b..98016785d 100644 --- a/src/core/server/graph/tenant/resolvers/index.ts +++ b/src/core/server/graph/tenant/resolvers/index.ts @@ -7,6 +7,7 @@ import Comment from "./comment"; import Mutation from "./mutation"; import Profile from "./profile"; import Query from "./query"; +import User from "./user"; const Resolvers: GQLResolver = { Asset, @@ -16,6 +17,7 @@ const Resolvers: GQLResolver = { Mutation, Profile, Query, + User, }; export default Resolvers; diff --git a/src/core/server/graph/tenant/resolvers/query.ts b/src/core/server/graph/tenant/resolvers/query.ts index 295b6c459..74362011f 100644 --- a/src/core/server/graph/tenant/resolvers/query.ts +++ b/src/core/server/graph/tenant/resolvers/query.ts @@ -5,7 +5,7 @@ const Query: GQLQueryTypeResolver = { comment: (source, { id }, ctx) => id ? ctx.loaders.Comments.comment.load(id) : null, settings: (source, args, ctx) => ctx.tenant, - me: (source, args, ctx) => ctx.user, + me: (source, args, ctx) => ctx.loaders.Users.me, }; export default Query; diff --git a/src/core/server/graph/tenant/resolvers/user.ts b/src/core/server/graph/tenant/resolvers/user.ts new file mode 100644 index 000000000..86bbbb90d --- /dev/null +++ b/src/core/server/graph/tenant/resolvers/user.ts @@ -0,0 +1,9 @@ +import { GQLUserTypeResolver } from "talk-server/graph/tenant/schema/__generated__/types"; +import { User } from "talk-server/models/User"; + +const User: GQLUserTypeResolver = { + comments: (asset, input, ctx) => + ctx.user ? ctx.loaders.Comments.forUser(ctx.user.id, input) : [], +}; + +export default User; diff --git a/src/core/server/models/comment.ts b/src/core/server/models/comment.ts index bec7cc382..dc64046c1 100644 --- a/src/core/server/models/comment.ts +++ b/src/core/server/models/comment.ts @@ -298,6 +298,30 @@ export async function retrieveCommentAssetConnection( return retrieveConnection(input, query); } +/** + * retrieveCommentUserConnection returns a Connection for a given User's + * comments. + * + * @param db database connection + * @param userID the User id for the comment to retrieve + * @param input connection configuration + */ +export async function retrieveCommentUserConnection( + db: Db, + tenantID: string, + userID: string, + input: ConnectionInput +) { + // Create the query. + const query = new Query(collection(db)).where({ + tenant_id: tenantID, + author_id: userID, + }); + + // Return a connection for the comments query. + return retrieveConnection(input, query); +} + /** * retrieveConnection returns a Connection for the given input and * Query. From f391d7b7ad6aadffcb90766a71b9abb3b99afa60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Curcio?= Date: Fri, 14 Sep 2018 12:37:25 -0300 Subject: [PATCH 06/35] Working comment history, styling in progress --- .../profile/components/CommentHistory.tsx | 13 ++++++++-- .../profile/components/HistoryComment.tsx | 26 +++++++++++++++++++ .../containers/CommentHistoryContainer.tsx | 2 ++ .../server/graph/tenant/resolvers/user.ts | 2 +- 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/core/client/stream/tabs/profile/components/HistoryComment.tsx diff --git a/src/core/client/stream/tabs/profile/components/CommentHistory.tsx b/src/core/client/stream/tabs/profile/components/CommentHistory.tsx index b2804adf8..256ce3514 100644 --- a/src/core/client/stream/tabs/profile/components/CommentHistory.tsx +++ b/src/core/client/stream/tabs/profile/components/CommentHistory.tsx @@ -1,14 +1,23 @@ import * as React from "react"; import { StatelessComponent } from "react"; import { CommentHistoryContainer_me as MeData } from "talk-stream/__generated__/CommentHistoryContainer_me.graphql"; -import { HorizontalGutter } from "talk-ui/components"; +import { HorizontalGutter, Typography } from "talk-ui/components"; +import HistoryComment from "./HistoryComment"; export interface CommentHistoryProps { me: MeData; } const CommentHistory: StatelessComponent = props => { - return Comments; + const comments = props.me.comments.edges.map(edge => edge.node); + return ( + + Comment History + {comments.map(comment => ( + + ))} + + ); }; export default CommentHistory; diff --git a/src/core/client/stream/tabs/profile/components/HistoryComment.tsx b/src/core/client/stream/tabs/profile/components/HistoryComment.tsx new file mode 100644 index 000000000..a315cb393 --- /dev/null +++ b/src/core/client/stream/tabs/profile/components/HistoryComment.tsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import { StatelessComponent } from "react"; +import { Flex, RelativeTime, Typography } from "talk-ui/components"; +import HTMLContent from "../../../components/HTMLContent"; + +export interface CommentHistoryProps { + comment: { + body: string | null; + createdAt: string; + }; +} + +const HistoryComment: StatelessComponent = props => { + return ( + + + {props.comment.body && {props.comment.body}} + +
+ +
+
+ ); +}; + +export default HistoryComment; diff --git a/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx b/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx index d46cec7d4..a009cdc4a 100644 --- a/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx +++ b/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx @@ -25,6 +25,8 @@ const enhanced = withFragmentContainer({ node { id body + createdAt + replyCount } } } diff --git a/src/core/server/graph/tenant/resolvers/user.ts b/src/core/server/graph/tenant/resolvers/user.ts index 86bbbb90d..2458f26f2 100644 --- a/src/core/server/graph/tenant/resolvers/user.ts +++ b/src/core/server/graph/tenant/resolvers/user.ts @@ -2,7 +2,7 @@ import { GQLUserTypeResolver } from "talk-server/graph/tenant/schema/__generated import { User } from "talk-server/models/User"; const User: GQLUserTypeResolver = { - comments: (asset, input, ctx) => + comments: (_, input, ctx) => ctx.user ? ctx.loaders.Comments.forUser(ctx.user.id, input) : [], }; From 52c8c8a625530d70432b99e59f87eadd50df1062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Curcio?= Date: Fri, 14 Sep 2018 13:03:26 -0300 Subject: [PATCH 07/35] Styling --- .../tabs/profile/components/HistoryComment.css | 7 +++++++ .../tabs/profile/components/HistoryComment.tsx | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 src/core/client/stream/tabs/profile/components/HistoryComment.css diff --git a/src/core/client/stream/tabs/profile/components/HistoryComment.css b/src/core/client/stream/tabs/profile/components/HistoryComment.css new file mode 100644 index 000000000..b0a8f73cb --- /dev/null +++ b/src/core/client/stream/tabs/profile/components/HistoryComment.css @@ -0,0 +1,7 @@ +.icon { + color: var(--palette-text-secondary); +} + +.sideBar { + min-width: 110px; +} diff --git a/src/core/client/stream/tabs/profile/components/HistoryComment.tsx b/src/core/client/stream/tabs/profile/components/HistoryComment.tsx index a315cb393..c5f73f2cc 100644 --- a/src/core/client/stream/tabs/profile/components/HistoryComment.tsx +++ b/src/core/client/stream/tabs/profile/components/HistoryComment.tsx @@ -1,7 +1,9 @@ import * as React from "react"; import { StatelessComponent } from "react"; -import { Flex, RelativeTime, Typography } from "talk-ui/components"; +import Timestamp from "talk-stream/components/Timestamp"; +import { Flex, Icon, Typography } from "talk-ui/components"; import HTMLContent from "../../../components/HTMLContent"; +import * as styles from "./HistoryComment.css"; export interface CommentHistoryProps { comment: { @@ -12,13 +14,19 @@ export interface CommentHistoryProps { const HistoryComment: StatelessComponent = props => { return ( - + {props.comment.body && {props.comment.body}} -
- -
+ + schedule + {props.comment.createdAt} +
); }; From cb2cfe1581ec7d65aaa4c05e130a9a2ba521b36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Curcio?= Date: Fri, 14 Sep 2018 17:52:55 -0300 Subject: [PATCH 08/35] Adding View Conversation functionality and styling --- ...CommentHistory.tsx => CommentsHistory.tsx} | 13 +- .../profile/components/HistoryComment.css | 14 +- .../profile/components/HistoryComment.tsx | 58 ++- .../tabs/profile/components/Profile.tsx | 10 +- .../containers/CommentHistoryContainer.tsx | 37 -- .../containers/CommentsHistoryContainer.tsx | 58 +++ .../profile/containers/ProfileContainer.tsx | 2 +- .../__snapshots__/renderReplies.spec.tsx.snap | 409 ------------------ src/core/server/graph/tenant/loaders/users.ts | 1 - 9 files changed, 128 insertions(+), 474 deletions(-) rename src/core/client/stream/tabs/profile/components/{CommentHistory.tsx => CommentsHistory.tsx} (55%) delete mode 100644 src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx create mode 100644 src/core/client/stream/tabs/profile/containers/CommentsHistoryContainer.tsx delete mode 100644 src/core/client/stream/test/comments/__snapshots__/renderReplies.spec.tsx.snap diff --git a/src/core/client/stream/tabs/profile/components/CommentHistory.tsx b/src/core/client/stream/tabs/profile/components/CommentsHistory.tsx similarity index 55% rename from src/core/client/stream/tabs/profile/components/CommentHistory.tsx rename to src/core/client/stream/tabs/profile/components/CommentsHistory.tsx index 256ce3514..879759d71 100644 --- a/src/core/client/stream/tabs/profile/components/CommentHistory.tsx +++ b/src/core/client/stream/tabs/profile/components/CommentsHistory.tsx @@ -1,23 +1,28 @@ import * as React from "react"; import { StatelessComponent } from "react"; -import { CommentHistoryContainer_me as MeData } from "talk-stream/__generated__/CommentHistoryContainer_me.graphql"; +import { CommentsHistoryContainer_me as MeData } from "talk-stream/__generated__/CommentsHistoryContainer_me.graphql"; import { HorizontalGutter, Typography } from "talk-ui/components"; import HistoryComment from "./HistoryComment"; export interface CommentHistoryProps { + goToConversation: () => void; me: MeData; } -const CommentHistory: StatelessComponent = props => { +const CommentsHistory: StatelessComponent = props => { const comments = props.me.comments.edges.map(edge => edge.node); return ( Comment History {comments.map(comment => ( - + ))} ); }; -export default CommentHistory; +export default CommentsHistory; diff --git a/src/core/client/stream/tabs/profile/components/HistoryComment.css b/src/core/client/stream/tabs/profile/components/HistoryComment.css index b0a8f73cb..2ab426a8a 100644 --- a/src/core/client/stream/tabs/profile/components/HistoryComment.css +++ b/src/core/client/stream/tabs/profile/components/HistoryComment.css @@ -2,6 +2,16 @@ color: var(--palette-text-secondary); } -.sideBar { - min-width: 110px; +.button, +.text { + color: var(--palette-text-secondary); + font-family: var(--font-family-sans-serif); + font-weight: var(--font-weight-medium); + font-size: calc(14rem / var(--rem-base)); + line-height: calc(18em / 14); + letter-spacing: 0; +} + +.sideBar { + min-width: 180px; } diff --git a/src/core/client/stream/tabs/profile/components/HistoryComment.tsx b/src/core/client/stream/tabs/profile/components/HistoryComment.tsx index c5f73f2cc..6af681546 100644 --- a/src/core/client/stream/tabs/profile/components/HistoryComment.tsx +++ b/src/core/client/stream/tabs/profile/components/HistoryComment.tsx @@ -1,7 +1,13 @@ import * as React from "react"; import { StatelessComponent } from "react"; import Timestamp from "talk-stream/components/Timestamp"; -import { Flex, Icon, Typography } from "talk-ui/components"; +import { + BaseButton, + Flex, + HorizontalGutter, + Icon, + Typography, +} from "talk-ui/components"; import HTMLContent from "../../../components/HTMLContent"; import * as styles from "./HistoryComment.css"; @@ -9,25 +15,49 @@ export interface CommentHistoryProps { comment: { body: string | null; createdAt: string; + replyCount: number | null; }; + goToConversation: () => void; } const HistoryComment: StatelessComponent = props => { return ( - - - {props.comment.body && {props.comment.body}} - - - schedule - {props.comment.createdAt} + + + + {props.comment.body && ( + {props.comment.body} + )} + + + + launch + + View Conversation + + + + schedule + {props.comment.createdAt} + + - + {!!props.comment.replyCount && ( + + reply + Replies {props.comment.replyCount} + + )} + ); }; diff --git a/src/core/client/stream/tabs/profile/components/Profile.tsx b/src/core/client/stream/tabs/profile/components/Profile.tsx index 516b7ac74..ff2450690 100644 --- a/src/core/client/stream/tabs/profile/components/Profile.tsx +++ b/src/core/client/stream/tabs/profile/components/Profile.tsx @@ -3,22 +3,20 @@ import { StatelessComponent } from "react"; import { PropTypesOf } from "talk-framework/types"; import UserBoxContainer from "talk-stream/containers/UserBoxContainer"; import { HorizontalGutter } from "talk-ui/components"; -import CommentHistoryContainer from "../containers/CommentHistoryContainer"; +import CommentsHistoryContainer from "../containers/CommentsHistoryContainer"; export interface ProfileProps { me: | PropTypesOf["me"] & - PropTypesOf["me"] + PropTypesOf["me"] | null; } const Profile: StatelessComponent = props => { return ( - - - {props.me && } - + + {props.me && } ); }; diff --git a/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx b/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx deleted file mode 100644 index a009cdc4a..000000000 --- a/src/core/client/stream/tabs/profile/containers/CommentHistoryContainer.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from "react"; -import { graphql } from "react-relay"; - -import { withFragmentContainer } from "talk-framework/lib/relay"; -import { CommentHistoryContainer_me as CommentsData } from "talk-stream/__generated__/CommentHistoryContainer_me.graphql"; - -import CommentHistory from "../components/CommentHistory"; - -interface CommentHistoryContainerProps { - me: CommentsData; -} - -export class CommentHistoryContainer extends React.Component< - CommentHistoryContainerProps -> { - public render() { - return ; - } -} -const enhanced = withFragmentContainer({ - me: graphql` - fragment CommentHistoryContainer_me on User { - comments { - edges { - node { - id - body - createdAt - replyCount - } - } - } - } - `, -})(CommentHistoryContainer); - -export default enhanced; diff --git a/src/core/client/stream/tabs/profile/containers/CommentsHistoryContainer.tsx b/src/core/client/stream/tabs/profile/containers/CommentsHistoryContainer.tsx new file mode 100644 index 000000000..fb6ba6344 --- /dev/null +++ b/src/core/client/stream/tabs/profile/containers/CommentsHistoryContainer.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import { graphql } from "react-relay"; +import { + withFragmentContainer, + withLocalStateContainer, +} from "talk-framework/lib/relay"; +import { CommentsHistoryContainer_me as CommentsData } from "talk-stream/__generated__/CommentsHistoryContainer_me.graphql"; +import { CommentsHistoryContainerLocal as Local } from "talk-stream/__generated__/CommentsHistoryContainerLocal.graphql"; +import CommentsHistory from "../components/CommentsHistory"; + +interface CommentsHistoryContainerProps { + local: Local; + me: CommentsData; +} + +export class CommentsHistoryContainer extends React.Component< + CommentsHistoryContainerProps +> { + private goToConversation = () => { + if (this.props.local.assetURL) { + window.open(this.props.local.assetURL, "_blank"); + } + }; + public render() { + return ( + + ); + } +} +const enhanced = withFragmentContainer({ + me: graphql` + fragment CommentsHistoryContainer_me on User { + comments { + edges { + node { + id + body + createdAt + replyCount + } + } + } + } + `, +})( + withLocalStateContainer( + graphql` + fragment CommentsHistoryContainerLocal on Local { + assetURL + } + ` + )(CommentsHistoryContainer) +); + +export default enhanced; diff --git a/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx b/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx index 6ece17835..3b91aec77 100644 --- a/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx +++ b/src/core/client/stream/tabs/profile/containers/ProfileContainer.tsx @@ -22,7 +22,7 @@ const enhanced = withFragmentContainer({ me: graphql` fragment ProfileContainer_me on User { ...UserBoxContainer_me - ...CommentHistoryContainer_me + ...CommentsHistoryContainer_me } `, })(StreamContainer); diff --git a/src/core/client/stream/test/comments/__snapshots__/renderReplies.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/renderReplies.spec.tsx.snap deleted file mode 100644 index 1b2669c4e..000000000 --- a/src/core/client/stream/test/comments/__snapshots__/renderReplies.spec.tsx.snap +++ /dev/null @@ -1,409 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders comment stream 1`] = ` -
-
-
-
- - -
-
- -
-
-
-
-
-
-
- - Markus - -
- -
-
-
-
-
- -
-
-
-
-
-
-
-
-
- - Markus - -
- -
-
-
-
-
- -
-
-
-
-
-
-
-
- - Markus - -
- -
-
-
-
-
- -
-
-
-
-
-
-
- - Lukas - -
- -
-
-
-
-
- -
-
-
-
-
-
-
-
-`; diff --git a/src/core/server/graph/tenant/loaders/users.ts b/src/core/server/graph/tenant/loaders/users.ts index 558981daa..0b77b370a 100644 --- a/src/core/server/graph/tenant/loaders/users.ts +++ b/src/core/server/graph/tenant/loaders/users.ts @@ -1,6 +1,5 @@ import DataLoader from "dataloader"; import Context from "talk-server/graph/tenant/context"; -// import { retrieveCommentUserConnection } from "talk-server/models/comment"; import { retrieveManyUsers, User } from "talk-server/models/user"; export default (ctx: Context) => ({ From 601436cf99b4b4f964f3a65f7e5722013ed7066d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Curcio?= Date: Fri, 14 Sep 2018 17:56:32 -0300 Subject: [PATCH 09/35] Updated snapshots --- .../__snapshots__/App.spec.tsx.snap | 35 +- .../__snapshots__/editComment.spec.tsx.snap | 4282 ++++++++--------- .../__snapshots__/loadMore.spec.tsx.snap | 609 +-- .../__snapshots__/permalinkView.spec.tsx.snap | 179 +- .../permalinkViewAssetNotFound.spec.tsx.snap | 65 +- ...permalinkViewCommentNotFound.spec.tsx.snap | 101 +- .../__snapshots__/postComment.spec.tsx.snap | 1933 ++++---- .../__snapshots__/postReply.spec.tsx.snap | 2500 +++++----- .../__snapshots__/renderReplies.spec.tsx.snap | 466 ++ .../__snapshots__/renderStream.spec.tsx.snap | 511 +- .../showAllReplies.spec.tsx.snap | 477 +- 11 files changed, 6195 insertions(+), 4963 deletions(-) create mode 100644 src/core/client/stream/test/comments/__snapshots__/renderReplies.spec.tsx.snap diff --git a/src/core/client/stream/components/__snapshots__/App.spec.tsx.snap b/src/core/client/stream/components/__snapshots__/App.spec.tsx.snap index d42a5a3d0..b67368e85 100644 --- a/src/core/client/stream/components/__snapshots__/App.spec.tsx.snap +++ b/src/core/client/stream/components/__snapshots__/App.spec.tsx.snap @@ -1,10 +1,37 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders comments 1`] = ` - - - + + + Comments + + + My Profile + + + + + + + + + + + `; diff --git a/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap index 89fa7f723..f24f5c40a 100644 --- a/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap @@ -2,212 +2,656 @@ exports[`cancel edit: edit canceled 1`] = `
-
+ + + +
- Signed in as - - Markus - - . -
-
- - Not you?  - -
+
- Sign Out - + + Not you?  + + +
+
+
+
+ +
+
+
+ + + +
+ +
+
+
+
+
+
+ + Powered by + + ⁨The Coral Project⁩ + + +
+ +
+
+
-
-
-
+
+`; + +exports[`edit a comment: edit form 1`] = ` +
+
    + + +
+
+
+
+
+
+
+ Signed in as + + Markus + + . +
+
+ + Not you?  + + +
+
+
+
+
+
+ +
+
+
+ + + +
+ +
+
+
+
+
+
- Markus + Powered by + + ⁨The Coral Project⁩ + +
+ +
+
+ +
+
+
+
+
+
+ + Markus +
+ +
+
+
+ + + +
+
+
+
+
+
+ + + Edit: + + remaining + +
+
+
-
-
- -
-
+
-
-
- - Lukas -
- + Lukas + +
+ +
-
-
-
- + +
-
+
`; -exports[`cancel edit: server response 1`] = ` +exports[`edit a comment: optimistic response 1`] = ` +
+
    + + +
+
+
+
+
+
+
+ Signed in as + + Markus + + . +
+
+ + Not you?  + + +
+
+
+
+
+
+ +
+
+
+ + + +
+ +
+
+
+
+
+
+ + Powered by + + ⁨The Coral Project⁩ + + +
+ +
+
+ +
+
+
+
+
+
+
+ + Markus + + +
+
+
+ +
+
+
+ + + +
+
+
+
+
+
+ + + Edit: + + remaining + +
+
+ + +
+
+ +
+
+
+
+
+
+ + Lukas + +
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+`; + +exports[`edit a comment: render stream 1`] = ` +
+
    + + +
+
+
+
+
+
+
+ Signed in as + + Markus + + . +
+
+ + Not you?  + + +
+
+
+
+
+
+ +
+
+
+ + + +
+ +
+
+
+
+
+
+ + Powered by + + ⁨The Coral Project⁩ + + +
+ +
+
+ +
+
+
+
+
+
+
+ + Markus + +
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+
+
+
+ + Lukas + +
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+`; + +exports[`edit a comment: server response 1`] = `
@@ -736,225 +2137,126 @@ exports[`cancel edit: server response 1`] = `
`; -exports[`edit a comment: edit form 1`] = ` +exports[`shows expiry message: edit form closed 1`] = `
-
+ + + +
- Signed in as - - Markus - - . -
-
- - Not you?  - - -
-
-
-
-
-
- -
-
-
- - - -
- -
-
-
-
-
+ Signed in as - Powered by - - ⁨The Coral Project⁩ - + Markus + .
- + + Not you?  + + +
-
-
-
-
-
-
- - Markus - - -
-
+
- - - Edit: - - remaining - -
-
- + Powered by + + ⁨The Coral Project⁩ + + +
-
-
-
-
- - Lukas - -
- -
-
-
-
-
- -
-
-
-
-
-
-
-`; - -exports[`edit a comment: optimistic response 1`] = ` -
-
-
-
-
-
- Signed in as - - Markus - - . -
-
- - Not you?  - - -
-
-
-
-
- -
-
-
- - - -
- -
-
-
-
- - Powered by - - ⁨The Coral Project⁩ - - -
- -
-
- -
-
-
-
-
-
- - Markus - - -
-
-
- -
-
- - - -
+ Markus +
+ +
+
+
+
-
-
- - - Edit: - - remaining - -
-
- - -
-
-
-
-
-
-
-
- - Lukas - -
- -
-
-
-
-
- -
-
-
-
-
-
-
-`; - -exports[`edit a comment: render stream 1`] = ` -
-
-
-
-
-
- Signed in as - - Markus - - . -
-
- - Not you?  - - -
-
-
-
-
-
- -
-
-
- - - -
- -
-
-
-
-
-
- - Powered by - - ⁨The Coral Project⁩ - - -
- -
-
- -
-
-
-
-
-
+ } + />
- - Markus - -
- -
-
-
-
-
- -
-
-
-
-
-
-
- - Lukas - -
- -
-
-
-
-
- -
-
-
-
-
-
-
-`; - -exports[`edit a comment: server response 1`] = ` -
-
-
-
-
-
- Signed in as - - Markus - - . -
-
- - Not you?  - - -
-
-
-
-
- -
-
-
- - - -
- -
-
-
-
- - Powered by - - ⁨The Coral Project⁩ - - -
- -
-
- -
-
-
-
-
-
- - Markus -
- + Lukas +
- ( - - Edited - - ) +
-
- -
-
-
-
- -
-
-
-
-
-
-
-
- - Lukas - -
- -
-
-
-
-
- -
-
-
-
-
-
-
-`; - -exports[`shows expiry message: edit form closed 1`] = ` -
-
-
-
-
-
- Signed in as - - Markus - - . -
-
- - Not you?  - - -
-
-
-
-
-
- -
-
-
- - - -
- -
-
-
-
-
-
- - Powered by - - ⁨The Coral Project⁩ - - -
- -
-
- -
-
-
-
-
-
+ } + />
- - Markus - -
- -
-
-
-
-
- -
-
-
-
-
-
-
-
-
- - Lukas - -
- -
-
-
-
-
- -
-
+
`; exports[`shows expiry message: edit time expired 1`] = `
-
+ + + +
- Signed in as - - Markus - - . -
-
- - Not you?  - - -
-
-
-
-
-
- -
-
-
- - - -
- -
-
-
-
-
+ Signed in as - Powered by - - ⁨The Coral Project⁩ - + Markus + .
- + + Not you?  + + +
-
-
-
-
-
-
- - Markus - - -
-
+
- - Edit time has expired. You can no longer edit this comment. Why not post another one? -
-
+ + Powered by + + ⁨The Coral Project⁩ + + +
-
-
- - Lukas - +
+ + Markus +
-
-
-
- + + +
+
+
+
+
+
- - Reply + - + Edit time has expired. You can no longer edit this comment. Why not post another one? +
+
+ +
+
+ +
+
+
+
+
+
+ + Lukas + +
+ +
+
+
+
+
+ +
-
+
`; diff --git a/src/core/client/stream/test/comments/__snapshots__/loadMore.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/loadMore.spec.tsx.snap index 84c4e89de..7b27a731f 100644 --- a/src/core/client/stream/test/comments/__snapshots__/loadMore.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/loadMore.spec.tsx.snap @@ -347,284 +347,22 @@ exports[`loads more comments 1`] = ` exports[`renders comment stream 1`] = `
-
-