diff --git a/.gitignore b/.gitignore index 50edc648d0..9b42991da7 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ playground.xcworkspace .DS_Store node_modules +npm-debug.log Example/Pods Example/compile_commands.json Example/Emission/Configuration.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cf192e6fd..8fc1144308 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ - [dev] Allows toggling the back button by pressing space - orta ###### Messaging + +- Adds an `ImagePreview` to each Conversation, Relay-ified messages - matt - Adds snapshot tests for active bids - luc - Update status label colors - luc - Renders active bids before Messages - luc diff --git a/Example/Podfile.lock b/Example/Podfile.lock index d37d271115..297af453d0 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -173,13 +173,13 @@ EXTERNAL SOURCES: :branch: fetch-user-details :git: https://github.com/artsy/Artsy-Authentication.git Emission: - :path: "../" + :path: ../ React: - :path: "../node_modules/react-native" + :path: ../node_modules/react-native SentryReactNative: - :path: "../node_modules/react-native-sentry" + :path: ../node_modules/react-native-sentry Yoga: - :path: "../node_modules/react-native/ReactCommon/yoga" + :path: ../node_modules/react-native/ReactCommon/yoga CHECKOUT OPTIONS: AppHub: diff --git a/data/schema.graphql b/data/schema.graphql index 653f80fe0a..60370a5781 100644 --- a/data/schema.graphql +++ b/data/schema.graphql @@ -1,8 +1,3 @@ -schema { - query: RootQueryType - mutation: RootMutationType -} - # One item in an aggregation type AggregationCount { # A globally unique ID. @@ -21,10 +16,7 @@ input AppendConversationThreadInput { # The email address of the message sender from: String! - - # An array of email addresses that the message should be sent to - to: [String] - message_body: String! + body_text: String! clientMutationId: String } @@ -792,6 +784,9 @@ type ArtworkContextFair { shows_connection( # Number of artworks to return section: String + + # Sorts for shows in a fair + sort: ShowSort = FEATURED_DESC after: String first: Int before: String @@ -1326,6 +1321,18 @@ enum ArtworkSorts { TITLE_DESC } +type AttachmentType { + # Attachment id. + id: String! + + # Content type of file. + content_type: String! + + # File name. + file_name: String! + download_url: String! +} + type Author { # A globally unique ID. __id: ID! @@ -1725,6 +1732,9 @@ type Fair { shows_connection( # Number of artworks to return section: String + + # Sorts for shows in a fair + sort: ShowSort = FEATURED_DESC after: String first: Int before: String @@ -2376,6 +2386,9 @@ type HomePageModuleContextFair { shows_connection( # Number of artworks to return section: String + + # Sorts for shows in a fair + sort: ShowSort = FEATURED_DESC after: String first: Int before: String @@ -2794,16 +2807,27 @@ type MessagePayloadType { } # A message in a conversation. -type MessageType { - # Impulse id. +type MessageType implements Node { + # A globally unique ID. + __id: ID! + + # Impulse message id. id: String! - # Email address of sender. - from_email_address: String! + # True if message is from the user to the partner. + is_from_user: Boolean + from_email_address: String - # A snippet of the full message - snippet: String! - radiation_message_id: String! + # Full unsanitized text. + raw_text: String! + attachments: [AttachmentType] + created_at( + convert_to_utc: Boolean + format: String + + # Specify a tz database time zone, otherwise falls back to `X-TIMEZONE` header + timezone: String + ): String } # A connection to a list of items. @@ -2824,6 +2848,16 @@ type MessageTypeEdge { cursor: String! } +type Mutation { + followArtist(input: FollowArtistInput!): FollowArtistPayload + updateCollectorProfile(input: UpdateCollectorProfileInput!): UpdateCollectorProfilePayload + updateConversation(input: UpdateConversationInput!): UpdateConversationPayload + + # Appending a message to a conversation thread + appendConversationThread(input: AppendConversationThreadInput!): AppendConversationThreadPayload + saveArtwork(input: SaveArtworkInput!): SaveArtworkPayload +} + input Near { lat: Float! lng: Float! @@ -3381,29 +3415,7 @@ type ProfileSearchEntity { is_publically_visible: Boolean } -type ResizedImageUrl { - factor: Float - width: Int - height: Int - url: String -} - -enum Role { - PARTICIPANT - OPERATOR -} - -type RootMutationType { - followArtist(input: FollowArtistInput!): FollowArtistPayload - updateCollectorProfile(input: UpdateCollectorProfileInput!): UpdateCollectorProfilePayload - updateBuyerOutcome(input: UpdateBuyerOutcomeInput!): UpdateBuyerOutcomePayload - - # Appending a message to a conversation thread - appendConversationThread(input: AppendConversationThreadInput!): AppendConversationThreadPayload - saveArtwork(input: SaveArtworkInput!): SaveArtworkPayload -} - -type RootQueryType { +type Query { # An Article article( # The ID of the Article @@ -3702,6 +3714,18 @@ type RootQueryType { viewer: Viewer } +type ResizedImageUrl { + factor: Float + width: Int + height: Int + url: String +} + +enum Role { + PARTICIPANT + OPERATOR +} + type Sale { # A globally unique ID. __id: ID! @@ -4180,6 +4204,21 @@ type ShowEdge { cursor: String! } +enum ShowSort { + START_AT_ASC + START_AT_DESC + END_AT_ASC + END_AT_DESC + UPDATED_AT_ASC + UPDATED_AT_DESC + NAME_ASC + NAME_DESC + FEATURED_ASC + FEATURED_DESC + SORTABLE_NAME_ASC + SORTABLE_NAME_DESC +} + type Status { gravity: StatusGravity @@ -4233,17 +4272,6 @@ enum TrendingMetrics { ARTIST_SEARCH } -input UpdateBuyerOutcomeInput { - buyer_outcome: BuyerOutcomeTypes! - ids: [String] - clientMutationId: String -} - -type UpdateBuyerOutcomePayload { - conversations: [ConversationType] - clientMutationId: String -} - input UpdateCollectorProfileInput { loyalty_applicant: Boolean professional_buyer: Boolean @@ -4292,6 +4320,17 @@ type UpdateCollectorProfilePayload { clientMutationId: String } +input UpdateConversationInput { + buyer_outcome: BuyerOutcomeTypes! + ids: [String] + clientMutationId: String +} + +type UpdateConversationPayload { + conversations: [ConversationType] + clientMutationId: String +} + # A wildcard used to support complex root queries in Relay type Viewer { # An Article diff --git a/data/schema.json b/data/schema.json index 3d5e220ff7..f00cd5740c 100644 --- a/data/schema.json +++ b/data/schema.json @@ -2,16 +2,16 @@ "data": { "__schema": { "queryType": { - "name": "RootQueryType" + "name": "Query" }, "mutationType": { - "name": "RootMutationType" + "name": "Mutation" }, "subscriptionType": null, "types": [ { "kind": "OBJECT", - "name": "RootQueryType", + "name": "Query", "description": null, "fields": [ { @@ -2371,6 +2371,11 @@ "name": "Me", "ofType": null }, + { + "kind": "OBJECT", + "name": "MessageType", + "ofType": null + }, { "kind": "OBJECT", "name": "NotificationsFeedItem", @@ -7377,6 +7382,16 @@ }, "defaultValue": null }, + { + "name": "sort", + "description": "Sorts for shows in a fair", + "type": { + "kind": "ENUM", + "name": "ShowSort", + "ofType": null + }, + "defaultValue": "FEATURED_DESC" + }, { "name": "after", "description": null, @@ -8061,6 +8076,89 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "ENUM", + "name": "ShowSort", + "description": null, + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "START_AT_ASC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "START_AT_DESC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "END_AT_ASC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "END_AT_DESC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT_ASC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UPDATED_AT_DESC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NAME_ASC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NAME_DESC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FEATURED_ASC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FEATURED_DESC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SORTABLE_NAME_ASC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SORTABLE_NAME_DESC", + "description": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, { "kind": "OBJECT", "name": "ShowConnection", @@ -13619,6 +13717,16 @@ }, "defaultValue": null }, + { + "name": "sort", + "description": "Sorts for shows in a fair", + "type": { + "kind": "ENUM", + "name": "ShowSort", + "ofType": null + }, + "defaultValue": "FEATURED_DESC" + }, { "name": "after", "description": null, @@ -19441,6 +19549,16 @@ }, "defaultValue": null }, + { + "name": "sort", + "description": "Sorts for shows in a fair", + "type": { + "kind": "ENUM", + "name": "ShowSort", + "ofType": null + }, + "defaultValue": "FEATURED_DESC" + }, { "name": "after", "description": null, @@ -24545,9 +24663,25 @@ "name": "MessageType", "description": "A message in a conversation.", "fields": [ + { + "name": "__id", + "description": "A globally unique ID.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "id", - "description": "Impulse id.", + "description": "Impulse message id.", "args": [], "type": { "kind": "NON_NULL", @@ -24561,9 +24695,33 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "is_from_user", + "description": "True if message is from the user to the partner.", + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "from_email_address", - "description": "Email address of sender.", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "raw_text", + "description": "Full unsanitized text.", "args": [], "type": { "kind": "NON_NULL", @@ -24578,8 +24736,84 @@ "deprecationReason": null }, { - "name": "snippet", - "description": "A snippet of the full message", + "name": "attachments", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "AttachmentType", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "created_at", + "description": null, + "args": [ + { + "name": "convert_to_utc", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "format", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "timezone", + "description": "Specify a tz database time zone, otherwise falls back to `X-TIMEZONE` header", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [ + { + "kind": "INTERFACE", + "name": "Node", + "ofType": null + } + ], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "AttachmentType", + "description": null, + "fields": [ + { + "name": "id", + "description": "Attachment id.", "args": [], "type": { "kind": "NON_NULL", @@ -24594,7 +24828,39 @@ "deprecationReason": null }, { - "name": "radiation_message_id", + "name": "content_type", + "description": "Content type of file.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "file_name", + "description": "File name.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "download_url", "description": null, "args": [], "type": { @@ -34497,7 +34763,7 @@ }, { "kind": "OBJECT", - "name": "RootMutationType", + "name": "Mutation", "description": null, "fields": [ { @@ -34555,7 +34821,7 @@ "deprecationReason": null }, { - "name": "updateBuyerOutcome", + "name": "updateConversation", "description": null, "args": [ { @@ -34566,7 +34832,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "UpdateBuyerOutcomeInput", + "name": "UpdateConversationInput", "ofType": null } }, @@ -34575,7 +34841,7 @@ ], "type": { "kind": "OBJECT", - "name": "UpdateBuyerOutcomePayload", + "name": "UpdateConversationPayload", "ofType": null }, "isDeprecated": false, @@ -35045,7 +35311,7 @@ }, { "kind": "INPUT_OBJECT", - "name": "UpdateBuyerOutcomeInput", + "name": "UpdateConversationInput", "description": null, "fields": null, "inputFields": [ @@ -35147,7 +35413,7 @@ }, { "kind": "OBJECT", - "name": "UpdateBuyerOutcomePayload", + "name": "UpdateConversationPayload", "description": null, "fields": [ { @@ -35219,21 +35485,7 @@ "defaultValue": null }, { - "name": "to", - "description": "An array of email addresses that the message should be sent to", - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - }, - { - "name": "message_body", + "name": "body_text", "description": null, "type": { "kind": "NON_NULL", diff --git a/externals/metaphysics b/externals/metaphysics index 75b91d0446..70cf93c8c4 160000 --- a/externals/metaphysics +++ b/externals/metaphysics @@ -1 +1 @@ -Subproject commit 75b91d04468266d9a62fc32a2a76a5515547a45f +Subproject commit 70cf93c8c4496a8ae97d3fe4070ff49574a4e400 diff --git a/package.json b/package.json index a76ae4df02..cb1930881d 100644 --- a/package.json +++ b/package.json @@ -131,4 +131,4 @@ "git add" ] } -} +} \ No newline at end of file diff --git a/src/lib/Components/Inbox/Conversations/Message.tsx b/src/lib/Components/Inbox/Conversations/Message.tsx index 0007ff86d8..0047985199 100644 --- a/src/lib/Components/Inbox/Conversations/Message.tsx +++ b/src/lib/Components/Inbox/Conversations/Message.tsx @@ -1,4 +1,6 @@ +import * as moment from "moment" import * as React from "react" +import * as Relay from "react-relay" import { BodyText, MetadataText, SmallHeadline } from "../Typography" @@ -47,29 +49,52 @@ const ArtworkPreviewContainer = styled.View` marginBottom: 10 ` -interface Props { - message: { - senderName: string - time: string - body: string - } +const ImagePreviewContainer = styled.View` + marginBottom: 10 +` + +interface Props extends RelayProps { + senderName: string artworkPreview?: JSX.Element + imagePreview?: JSX.Element } -export default class Message extends React.Component { +export class Message extends React.Component { render() { + const date = moment(this.props.message.created_at).fromNow(true) return (
- {this.props.message.senderName} - {this.props.message.time} + {this.props.senderName} + {date}
{this.props.artworkPreview && {this.props.artworkPreview}} - {this.props.message.body.split("\n\nAbout")[0]} + {this.props.imagePreview && {this.props.imagePreview}} + {this.props.message.raw_text.split("\n\nAbout")[0]}
) } } + +export default Relay.createContainer(Message, { + fragments: { + message: () => Relay.QL` + fragment on MessageType { + raw_text + created_at + is_from_user + } + `, + }, +}) + +interface RelayProps { + message: { + raw_text: string | null + created_at: string | null + is_from_user: boolean + } +} diff --git a/src/lib/Components/Inbox/Conversations/ArtworkPreview.tsx b/src/lib/Components/Inbox/Conversations/Previews/ArtworkPreview.tsx similarity index 89% rename from src/lib/Components/Inbox/Conversations/ArtworkPreview.tsx rename to src/lib/Components/Inbox/Conversations/Previews/ArtworkPreview.tsx index bce20d958d..a9336c06f6 100644 --- a/src/lib/Components/Inbox/Conversations/ArtworkPreview.tsx +++ b/src/lib/Components/Inbox/Conversations/Previews/ArtworkPreview.tsx @@ -3,12 +3,12 @@ import * as Relay from "react-relay" import { TouchableHighlight } from "react-native" -import { PreviewText as P, Subtitle } from "../Typography" +import { PreviewText as P, Subtitle } from "../../Typography" import styled from "styled-components/native" -import colors from "../../../../data/colors" -import fonts from "../../../../data/fonts" -import OpaqueImageView from "../../OpaqueImageView" +import colors from "../../../../../data/colors" +import fonts from "../../../../../data/fonts" +import OpaqueImageView from "../../../OpaqueImageView" const Container = styled.View` borderWidth: 1 diff --git a/src/lib/Components/Inbox/Conversations/Previews/ImagePreview.tsx b/src/lib/Components/Inbox/Conversations/Previews/ImagePreview.tsx new file mode 100644 index 0000000000..e924f290f9 --- /dev/null +++ b/src/lib/Components/Inbox/Conversations/Previews/ImagePreview.tsx @@ -0,0 +1,57 @@ +import * as React from "react" +import * as Relay from "react-relay" + +import { TouchableHighlight } from "react-native" + +import styled from "styled-components/native" +import colors from "../../../../../data/colors" +import fonts from "../../../../../data/fonts" +import OpaqueImageView from "../../../OpaqueImageView" + +const Container = styled.View` + borderWidth: 1 + borderColor: ${colors["gray-regular"]} + flexDirection: row +` + +const VerticalLayout = styled.View` + flex: 1 + flex-direction: column +` + +const Image = styled(OpaqueImageView)` + marginTop: 12 + marginLeft: 12 + marginBottom: 12 + width: 80 + height: 55 +` + +export class ImagePreview extends React.Component { + render() { + return ( + + + + + + ) + } +} + +export default Relay.createContainer(ImagePreview, { + fragments: { + imageAttachment: () => Relay.QL` + fragment on AttachmentType { + download_url + } + `, + }, +}) + +interface RelayProps { + imageAttachment: { + download_url?: string + } + onSelected?: () => void +} diff --git a/src/lib/Components/Inbox/Conversations/__stories__/ArtworkPreview.story.tsx b/src/lib/Components/Inbox/Conversations/__stories__/ArtworkPreview.story.tsx index f00905a905..917a5fa55c 100644 --- a/src/lib/Components/Inbox/Conversations/__stories__/ArtworkPreview.story.tsx +++ b/src/lib/Components/Inbox/Conversations/__stories__/ArtworkPreview.story.tsx @@ -3,7 +3,7 @@ import * as React from "react" import "react-native" import StubContainer from "react-storybooks-relay-container" -import ArtworkPreview from "../ArtworkPreview" +import ArtworkPreview from "../Previews/ArtworkPreview" const artwork = { id: "kara-walker-canisters-1", diff --git a/src/lib/Components/Inbox/Conversations/__tests__/ArtworkPreview-tests.tsx b/src/lib/Components/Inbox/Conversations/__tests__/ArtworkPreview-tests.tsx index 221db62252..8c99f7b6be 100644 --- a/src/lib/Components/Inbox/Conversations/__tests__/ArtworkPreview-tests.tsx +++ b/src/lib/Components/Inbox/Conversations/__tests__/ArtworkPreview-tests.tsx @@ -3,7 +3,7 @@ import * as React from "react" import "react-native" import * as renderer from "react-test-renderer" -import ArtworkPreview from "../ArtworkPreview" +import ArtworkPreview from "../Previews/ArtworkPreview" it("renders correctly", () => { const tree = renderer.create() diff --git a/src/lib/Components/Inbox/Conversations/__tests__/Message-tests.tsx b/src/lib/Components/Inbox/Conversations/__tests__/Message-tests.tsx index 996cd45452..47d70e999b 100644 --- a/src/lib/Components/Inbox/Conversations/__tests__/Message-tests.tsx +++ b/src/lib/Components/Inbox/Conversations/__tests__/Message-tests.tsx @@ -1,3 +1,4 @@ +import * as moment from "moment" import * as React from "react" import "react-native" import * as renderer from "react-test-renderer" @@ -8,7 +9,13 @@ it("looks correct when rendered", () => { // tslint:disable-next-line:max-line-length const messageBody = "Hi, I'm interested in purchasing this work. Could you please provide more information about the piece, including price?" - const props = { senderName: "Sarah Scott", key: 0, time: "11:00AM", body: messageBody } - const tree = renderer.create().toJSON() + const senderName = "Sarah" + const props = { + key: 0, + created_at: moment().subtract(30, "minutes").toISOString(), + raw_text: messageBody, + is_from_user: true, + } + const tree = renderer.create().toJSON() expect(tree).toMatchSnapshot() }) diff --git a/src/lib/Components/Inbox/Conversations/__tests__/__snapshots__/Message-tests.tsx.snap b/src/lib/Components/Inbox/Conversations/__tests__/__snapshots__/Message-tests.tsx.snap index f4a1c158bc..128370d514 100644 --- a/src/lib/Components/Inbox/Conversations/__tests__/__snapshots__/Message-tests.tsx.snap +++ b/src/lib/Components/Inbox/Conversations/__tests__/__snapshots__/Message-tests.tsx.snap @@ -91,7 +91,7 @@ exports[`looks correct when rendered 1`] = ` ] } > - SARAH SCOTT + SARAH - 11:00AM + 30 MINUTES { imageURL() { const imageURL = this.props.imageURL + if (this.props.skipGemini) { + return imageURL + } if (imageURL) { // Either scale or crop, based on if an aspect ratio is available. const type = this.state.aspectRatio ? "fit" : "fill" diff --git a/src/lib/Containers/Conversation.tsx b/src/lib/Containers/Conversation.tsx index 65b4a928c1..1c9c083015 100644 --- a/src/lib/Containers/Conversation.tsx +++ b/src/lib/Containers/Conversation.tsx @@ -7,9 +7,10 @@ import { FlatList, ImageURISource, ViewProperties } from "react-native" import styled from "styled-components/native" import colors from "../../data/colors" -import ArtworkPreview from "../Components/Inbox/Conversations/ArtworkPreview" import Composer from "../Components/Inbox/Conversations/Composer" import Message from "../Components/Inbox/Conversations/Message" +import ArtworkPreview from "../Components/Inbox/Conversations/Previews/ArtworkPreview" +import ImagePreview from "../Components/Inbox/Conversations/Previews/ImagePreview" import ARSwitchBoard from "../NativeModules/SwitchBoard" // tslint:disable-next-line:no-var-requires @@ -61,21 +62,20 @@ const ComposerContainer = styled.View` ` export class Conversation extends React.Component { - isFromUser(message) { - /** - * this is a quick hacky way to alternate between user/partner messages; will be changed once we have actual email - * data - */ - return message.from_email_address === this.props.me.conversation.from.email - } - - renderMessage(message) { + renderMessage({ item }) { const artwork = this.props.me.conversation.artworks[0] + const conversation = this.props.me.conversation + const partnerName = conversation.to.name + const senderName = item.is_from_user ? conversation.from.name : partnerName + const hasImageAttachment = item.attachments.length > 0 && item.attachments[0].content_type === "image/jpeg" + return ( } artworkPreview={ - !message.index && + item.first_message && ARSwitchBoard.presentNavigationViewController(this, artwork.href)} @@ -88,19 +88,11 @@ export class Conversation extends React.Component { render() { const conversation = this.props.me.conversation const partnerName = conversation.to.name - const artwork = conversation.artworks[0] - const temporaryTimestamp = "11:00AM" - - // Ideally we will use a Relay fragment in the Message component, but for now this is good enough - const messageData = conversation.messages.edges.reverse().map(({ node }, index) => { - return { - senderName: this.isFromUser(node) ? conversation.from.name : partnerName, - key: index, - time: temporaryTimestamp, - body: node.snippet, - } + const messages = this.props.me.conversation.messages.edges.map(({ node }, index) => { + node.first_message = index === 0 + node.key = node.id + return node }) - return (
@@ -111,7 +103,7 @@ export class Conversation extends React.Component {
@@ -138,16 +130,21 @@ export default Relay.createContainer(Conversation, { name } messages(first: 10) { + pageInfo { + hasNextPage + } edges { node { - snippet - from_email_address + id + ${Message.getFragment("message")} + attachments { + content_type + download_url + } } } } artworks @relay (plural: true) { - title - artist_names href ${ArtworkPreview.getFragment("artwork")} } diff --git a/src/lib/Containers/__tests__/Conversation-tests.tsx b/src/lib/Containers/__tests__/Conversation-tests.tsx index 8586cbb50c..b18175d5b6 100644 --- a/src/lib/Containers/__tests__/Conversation-tests.tsx +++ b/src/lib/Containers/__tests__/Conversation-tests.tsx @@ -1,3 +1,4 @@ +import * as moment from "moment" import * as React from "react" import "react-native" import * as renderer from "react-test-renderer" @@ -21,8 +22,11 @@ const props = { edges: [ { node: { - snippet: "Adoro! Por favor envie-me mais informações", + id: 222, + raw_text: "Adoro! Por favor envie-me mais informações", from_email_address: "anita@garibaldi.br", + attachments: [], + created_at: "2017-06-26T14:14:35.538Z", }, }, ], diff --git a/src/lib/Containers/__tests__/__snapshots__/Conversation-tests.tsx.snap b/src/lib/Containers/__tests__/__snapshots__/Conversation-tests.tsx.snap index 006e5e9ef7..6f27b1787f 100644 --- a/src/lib/Containers/__tests__/__snapshots__/Conversation-tests.tsx.snap +++ b/src/lib/Containers/__tests__/__snapshots__/Conversation-tests.tsx.snap @@ -91,10 +91,13 @@ exports[`looks correct when rendered 1`] = ` data={ Array [ Object { - "body": "Adoro! Por favor envie-me mais informações", - "key": 0, - "senderName": "Anita Garibaldi", - "time": "11:00AM", + "attachments": Array [], + "created_at": "2017-06-26T14:14:35.538Z", + "first_message": true, + "from_email_address": "anita@garibaldi.br", + "id": 222, + "key": 222, + "raw_text": "Adoro! Por favor envie-me mais informações", }, ] } @@ -223,7 +226,7 @@ exports[`looks correct when rendered 1`] = ` ] } > - ANITA GARIBALDI + KIMBERLY KLARK
- 11:00AM + A DAY Relay.QL` query { - me { - ${component.getFragment("me", params)} - } + me { + ${component.getFragment("me", params)} + } } `, }