import * as React from "react" import { graphql, withApollo, compose } from "react-apollo" import Stream from "../../Stream" import Component from "./component" import { query, badgeQuery, withClearBadge, newNotification } from "./graphql" const moment = require("moment") moment.locale("th") const withData = graphql(query, { props: ({ data }) => data && ({ loading: data.loading, refetch: data.refetch, notificationBadge: data ? data.notificationBadge : null, notifications: data && data.notifications ? data.notifications.nodes : null, hasNextPage: data && data.notifications ? data.notifications.hasNextPage : null, fetchMore: () => data && data.fetchMore({ variables: { after: data.notifications.endCursor }, updateQuery: (previousResult, { fetchMoreResult }) => { const newNotifications = fetchMoreResult.notifications console.log( newNotifications.endCursor, previousResult.notifications.endCursor ) if ( newNotifications.endCursor !== previousResult.notifications.endCursor ) { return { ...previousResult, notificationBadge: fetchMoreResult.notificationBadge, notifications: { ...previousResult.notifications, endCursor: newNotifications.endCursor, hasNextPage: newNotifications.hasNextPage, nodes: [].concat( previousResult.notifications.nodes, newNotifications.nodes ) } } } } } as any) }), options: (props) => ({ context: { service: "notification" }, variables: {}, ssr: false }) }) const enhance = compose(withData, withApollo, withClearBadge) function updateNotificationInfo(client, notifications, badge) { const data = client.readQuery({ query, variables: {} }) data.notificationBadge = badge if (notifications && notifications.length && data.notifications) { // tslint:disable-next-line:prefer-for-of for (let i = 0; i < notifications.length; i++) { const n: any = notifications[i] const node = data.notifications.nodes.find((n2) => n._id === n2._id) console.log("will add node", node, n) if (!node) { data.notifications.nodes = ( [] as any ).concat([n], data.notifications.nodes) } } } client.writeQuery({ query, variables: {}, data }) } class Container extends React.Component { public onAction = async (action) => { try { if (action.type === "stream/open") { let latestId let data = this.props.client.readQuery({ query, variables: {} }) if (!data.notifications) { await this.props.refetch() data = this.props.client.readQuery({ query, variables: {} }) } latestId = data.notifications.nodes.length ? data.notifications.nodes[0]._id : null const result = await this.props.client.query({ query: newNotification, variables: { latestId }, context: { service: "notification" }, fetchPolicy: "network-only" }) if (result && result.data.newNotifications) { updateNotificationInfo( this.props.client, result.data.newNotifications, result.data.notificationBadge ) } } if (action.type === "notification/insert") { const data = this.props.client.readQuery({ query: badgeQuery }) const addedNotification = Object.assign( { __typename: "Notification" }, action.payload ) updateNotificationInfo( this.props.client, [addedNotification], data.notificationBadge >= 0 ? data.notificationBadge + 1 : null ) } else if (action.type === "notification/clear-badge-count") { updateNotificationInfo(this.props.client, [], 0) } } catch (error) { console.error("apply action error", error) } } public render() { return [ , ] } } export default enhance(Container)