From 3c259591886a9aa7c8e2bf10a35f064c8f7e2814 Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Wed, 22 Jan 2020 17:23:41 -0500 Subject: [PATCH 01/29] Convert GroupCelebrate to TypeScript --- src/containers/CelebrateFeed/index.tsx | 198 ++++++++++------------- src/containers/Groups/GroupCelebrate.tsx | 115 ++++++------- src/selectors/celebration.ts | 2 +- 3 files changed, 149 insertions(+), 166 deletions(-) diff --git a/src/containers/CelebrateFeed/index.tsx b/src/containers/CelebrateFeed/index.tsx index 655c9d4858..139568b575 100644 --- a/src/containers/CelebrateFeed/index.tsx +++ b/src/containers/CelebrateFeed/index.tsx @@ -1,136 +1,116 @@ -import React, { Component } from 'react'; -import { SectionList } from 'react-native'; +import React, { useState } from 'react'; +import { SectionList, View } from 'react-native'; import { connect } from 'react-redux-legacy'; -import PropTypes from 'prop-types'; -import { View } from 'react-native'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; import { DateComponent } from '../../components/common'; -import CelebrateItem from '../../components/CelebrateItem'; +import CelebrateItemCard from '../../components/CelebrateItem'; import { DateConstants } from '../../components/DateComponent'; import { keyExtractorId } from '../../utils/common'; import CelebrateFeedHeader from '../CelebrateFeedHeader'; import ShareStoryInput from '../Groups/ShareStoryInput'; +import { CelebrateItem } from '../../selectors/celebration'; +import { Organization } from '../../reducers/organizations'; import styles from './styles'; -class CelebrateFeed extends Component { - // @ts-ignore - constructor(props) { - super(props); - // isListScrolled works around a known issue with SectionList in RN. see commit msg for details. - this.state = { ...this.state, isListScrolled: false }; - } +type CelebrateSection = { id: number; date: string; data: CelebrateItem[] }; - // @ts-ignore - renderSectionHeader = ({ section: { date } }) => { - const { title, header } = styles; - - return ( - - - - ); - }; +export interface CelebrateFeedProps { + dispatch: ThunkDispatch<{}, {}, AnyAction>; + items: CelebrateSection[]; + organization: Organization; + refreshing: boolean; + refreshCallback: () => void; + itemNamePressable: boolean; + isMember?: boolean; + noHeader?: boolean; + onClearNotification?: () => void; + loadMoreItemsCallback: () => void; +} - // @ts-ignore - renderItem = ({ item }) => { - const { - // @ts-ignore - organization, - // @ts-ignore - itemNamePressable, - // @ts-ignore - onClearNotification, - // @ts-ignore - refreshCallback, - } = this.props; +const CelebrateFeed = ({ + dispatch, + items, + organization, + refreshing, + refreshCallback, + itemNamePressable, + isMember, + noHeader, + onClearNotification, + loadMoreItemsCallback, +}: CelebrateFeedProps) => { + const [isListScrolled, setIsListScrolled] = useState(false); - return ( - ( + + - ); - }; + + ); - handleOnEndReached = () => { - // @ts-ignore - if (this.state.isListScrolled) { - // @ts-ignore - this.props.loadMoreItemsCallback(); - this.setState({ isListScrolled: false }); - } - }; + const renderItem = ({ item }: { item: CelebrateItem }) => ( + + ); - handleEndDrag = () => { - // @ts-ignore - if (!this.state.isListScrolled) { - this.setState({ isListScrolled: true }); + const handleOnEndReached = () => { + if (isListScrolled) { + loadMoreItemsCallback(); + setIsListScrolled(false); } }; - handleRefreshing = () => { - // @ts-ignore - this.props.refreshCallback(); - }; - - renderHeader = () => { - // @ts-ignore - const { isMember, organization, dispatch, refreshCallback } = this.props; - return ( - <> - // @ts-ignore - - - - ); + const handleEndDrag = () => { + if (!isListScrolled) { + setIsListScrolled(true); + } }; - render() { - // @ts-ignore - const { items, refreshing, noHeader } = this.props; + const handleRefreshing = () => refreshCallback(); - return ( - ( + <> + + - ); - } -} + + ); -// @ts-ignore -CelebrateFeed.propTypes = { - items: PropTypes.array.isRequired, - organization: PropTypes.object.isRequired, - refreshing: PropTypes.bool, - refreshingCallback: PropTypes.func, - itemNamePressable: PropTypes.bool, - isMember: PropTypes.bool, - noHeader: PropTypes.bool, + return ( + + ); }; export default connect()(CelebrateFeed); diff --git a/src/containers/Groups/GroupCelebrate.tsx b/src/containers/Groups/GroupCelebrate.tsx index 7db3c7bf57..6f46ecb326 100644 --- a/src/containers/Groups/GroupCelebrate.tsx +++ b/src/containers/Groups/GroupCelebrate.tsx @@ -1,7 +1,9 @@ -import React, { Component } from 'react'; +import React, { useState, useEffect } from 'react'; import { connect } from 'react-redux-legacy'; -import { withTranslation } from 'react-i18next'; +import { useTranslation } from 'react-i18next'; import moment from 'moment'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; import CelebrateFeed from '../CelebrateFeed'; import { @@ -10,7 +12,10 @@ import { } from '../../actions/celebration'; import { refreshCommunity } from '../../actions/organizations'; import { organizationSelector } from '../../selectors/organizations'; -import { celebrationSelector } from '../../selectors/celebration'; +import { + celebrationSelector, + CelebrateItem, +} from '../../selectors/celebration'; import { momentUtc, refresh, @@ -19,73 +24,71 @@ import { } from '../../utils/common'; import { getReportedComments } from '../../actions/reportComments'; import { orgPermissionSelector } from '../../selectors/people'; +import { AuthState } from '../../reducers/auth'; +import { OrganizationsState } from '../../reducers/organizations'; +import { Organization } from '../../reducers/organizations'; import Analytics from '../Analytics'; -// @ts-ignore -@withTranslation('groupsCelebrate') -class GroupCelebrate extends Component { - state = { refreshing: false }; +export interface GroupCelebrateProps { + dispatch: ThunkDispatch<{ organizations: OrganizationsState }, {}, AnyAction>; + organization: Organization; + shouldQueryReport: boolean; + celebrateItems: { id: number; date: string; data: CelebrateItem[] }[]; + pagination: any; +} - componentDidMount() { - if (this.shouldLoadFeed()) { - this.loadItems(); - } - } +const GroupCelebrate = ({ + dispatch, + organization, + shouldQueryReport, + celebrateItems, + pagination, +}: GroupCelebrateProps) => { + const [refreshing, setRefreshing] = useState(false); - shouldLoadFeed = () => { - // @ts-ignore - const { pagination, celebrateItems } = this.props; + const shouldLoadFeed = () => + !celebrateItems || + celebrateItems.length === 0 || + pagination.page === 0 || + moment().diff(momentUtc(celebrateItems[0].date), 'days', true) > 1; - return ( - !celebrateItems || - celebrateItems.length === 0 || - pagination.page === 0 || - moment().diff(momentUtc(celebrateItems[0].date), 'days', true) > 1 - ); - }; + const loadItems = () => dispatch(getGroupCelebrateFeed(organization.id)); - loadItems = () => { - // @ts-ignore - const { dispatch, organization } = this.props; - dispatch(getGroupCelebrateFeed(organization.id)); - }; + useEffect(() => { + shouldLoadFeed() && loadItems(); + }, []); - reloadItems = () => { - // @ts-ignore - const { dispatch, organization, shouldQueryReport } = this.props; + const reloadItems = () => { dispatch(refreshCommunity(organization.id)); shouldQueryReport && dispatch(getReportedComments(organization.id)); return dispatch(reloadGroupCelebrateFeed(organization.id)); }; - refreshItems = () => { - refresh(this, this.reloadItems); - }; + const refreshItems = () => refresh(_, reloadItems); - render() { - const { refreshing } = this.state; - // @ts-ignore - const { celebrateItems, organization } = this.props; - - return ( - <> - - - - ); - } -} + return ( + <> + + + + ); +}; -// @ts-ignore -const mapStateToProps = ({ auth, organizations }, { orgId }) => { +const mapStateToProps = ( + { + auth, + organizations, + }: { auth: AuthState; organizations: OrganizationsState }, + { orgId }: { orgId: string }, +) => { const organization = organizationSelector({ organizations }, { orgId }); const myOrgPermission = orgPermissionSelector( {}, diff --git a/src/selectors/celebration.ts b/src/selectors/celebration.ts index e1d58e3f06..9d994bbab5 100644 --- a/src/selectors/celebration.ts +++ b/src/selectors/celebration.ts @@ -5,7 +5,7 @@ import { CELEBRATEABLE_TYPES } from '../constants'; import { OrganizationsState } from '../reducers/organizations'; // eslint-disable-next-line @typescript-eslint/no-explicit-any -type CelebrateItem = any; +export type CelebrateItem = any; export const celebrationItemSelector = createSelector( ({ organizations }: { organizations: OrganizationsState }) => From 35ae94876ad6c9c312981720e375ff62120d4718 Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Thu, 23 Jan 2020 09:50:24 -0500 Subject: [PATCH 02/29] New gql query --- src/containers/CelebrateFeed/index.tsx | 128 ++++++++++++++++++----- src/containers/Groups/GroupCelebrate.tsx | 1 - src/selectors/celebration.ts | 43 +++++--- 3 files changed, 129 insertions(+), 43 deletions(-) diff --git a/src/containers/CelebrateFeed/index.tsx b/src/containers/CelebrateFeed/index.tsx index 139568b575..0af3b2672b 100644 --- a/src/containers/CelebrateFeed/index.tsx +++ b/src/containers/CelebrateFeed/index.tsx @@ -3,6 +3,8 @@ import { SectionList, View } from 'react-native'; import { connect } from 'react-redux-legacy'; import { ThunkDispatch } from 'redux-thunk'; import { AnyAction } from 'redux'; +import gql from 'graphql-tag'; +import { useQuery } from '@apollo/react-hooks'; import { DateComponent } from '../../components/common'; import CelebrateItemCard from '../../components/CelebrateItem'; @@ -10,18 +12,50 @@ import { DateConstants } from '../../components/DateComponent'; import { keyExtractorId } from '../../utils/common'; import CelebrateFeedHeader from '../CelebrateFeedHeader'; import ShareStoryInput from '../Groups/ShareStoryInput'; -import { CelebrateItem } from '../../selectors/celebration'; +import { + celebrationSelector, + CelebrateFeedSection, +} from '../../selectors/celebration'; import { Organization } from '../../reducers/organizations'; +import { useRefreshing } from '../../utils/hooks/useRefreshing'; +import { GetCelebrateFeed } from './__generated__/GetCelebrateFeed'; import styles from './styles'; -type CelebrateSection = { id: number; date: string; data: CelebrateItem[] }; +export const GET_CELEBRATE_FEED = gql` + query GetCelebrateFeed($communityId: [ID!], $celebrateCursor: String) { + community(id: $communityId) { + celebrationItems( + sortBy: createdAt_ASC + first: 25 + after: $celebrateCursor + ) { + nodes { + id + adjectiveAttributeName + adjectiveAttributeValue + celebrateableId + celebrateableType + changedAttributeName + changedAttributeValue + commentsCount + liked + likesCount + objectDescription + subjectPersonName + } + pageInfo { + endCursor + hasNextPage + } + } + } + } +`; export interface CelebrateFeedProps { dispatch: ThunkDispatch<{}, {}, AnyAction>; - items: CelebrateSection[]; organization: Organization; - refreshing: boolean; refreshCallback: () => void; itemNamePressable: boolean; isMember?: boolean; @@ -32,22 +66,81 @@ export interface CelebrateFeedProps { const CelebrateFeed = ({ dispatch, - items, organization, - refreshing, refreshCallback, itemNamePressable, isMember, noHeader, onClearNotification, - loadMoreItemsCallback, }: CelebrateFeedProps) => { const [isListScrolled, setIsListScrolled] = useState(false); + const { + data: { + community: { + celebrationItems: { + nodes = [], + pageInfo: { endCursor = null, hasNextPage = true } = {}, + } = {}, + } = {}, + } = {}, + fetchMore, + refetch, + } = useQuery(GET_CELEBRATE_FEED, { + variables: { + communityId: [organization.id], + }, + pollInterval: 30000, + }); + + const celebrationItems = celebrationSelector({ celebrateItems: nodes }); + + const { isRefreshing, refresh } = useRefreshing(refetch); + + const handleRefreshing = () => refresh(); + + const handleOnEndReached = () => { + if (isListScrolled && hasNextPage) { + fetchMore({ + variables: { + communityId: [organization.id], + celebrateCursor: endCursor, + }, + updateQuery: (prev, { fetchMoreResult }) => + fetchMoreResult + ? { + ...prev, + ...fetchMoreResult, + community: { + ...prev.community, + ...fetchMoreResult.community, + celebrationItems: { + ...prev.community.celebrationItems, + ...fetchMoreResult.community.celebrationItems, + nodes: [ + ...(prev.community.celebrationItems.nodes || []), + ...(fetchMoreResult.community.celebrationItems.nodes || + []), + ], + }, + }, + } + : prev, + }); + setIsListScrolled(false); + } + }; + + const handleEndDrag = () => { + if (!isListScrolled) { + setIsListScrolled(true); + } + }; + const renderSectionHeader = ({ section: { date }, }: { - section: CelebrateSection; + section: CelebrateFeedSection; }) => ( ); - const handleOnEndReached = () => { - if (isListScrolled) { - loadMoreItemsCallback(); - setIsListScrolled(false); - } - }; - - const handleEndDrag = () => { - if (!isListScrolled) { - setIsListScrolled(true); - } - }; - - const handleRefreshing = () => refreshCallback(); - const renderHeader = () => ( <> @@ -96,7 +174,7 @@ const CelebrateFeed = ({ return ( @@ -29,20 +33,20 @@ export const celebrationItemSelector = createSelector( ); export const celebrationSelector = createSelector( - ({ celebrateItems }: { celebrateItems: CelebrateItem[] }) => celebrateItems, + ({ + celebrateItems, + }: { + celebrateItems: GetCelebrateFeed_community_celebrationItems_nodes[]; + }) => celebrateItems, celebrateItems => { const filteredCelebrateItems = filterCelebrationFeedItems(celebrateItems); const sortByDate = filteredCelebrateItems; sortByDate.sort(compare); - const dateSections: { - id: number; - date: string; - data: CelebrateItem[]; - }[] = []; - sortByDate.forEach((item: CelebrateItem) => { + const dateSections: CelebrateFeedSection[] = []; + sortByDate.forEach(item => { const length = dateSections.length; - const itemMoment = momentUtc(item.changed_attribute_value).local(); + const itemMoment = momentUtc(item.changedAttributeValue).local(); if ( length > 0 && @@ -55,7 +59,7 @@ export const celebrationSelector = createSelector( } else { dateSections.push({ id: dateSections.length, - date: item.changed_attribute_value, + date: item.changedAttributeValue, data: [item], }); } @@ -65,9 +69,12 @@ export const celebrationSelector = createSelector( }, ); -const compare = (a: CelebrateItem, b: CelebrateItem) => { - const aValue = a.changed_attribute_value, - bValue = b.changed_attribute_value; +const compare = ( + a: GetCelebrateFeed_community_celebrationItems_nodes, + b: GetCelebrateFeed_community_celebrationItems_nodes, +) => { + const aValue = a.changedAttributeValue, + bValue = b.changedAttributeValue; if (aValue < bValue) { return 1; @@ -78,7 +85,9 @@ const compare = (a: CelebrateItem, b: CelebrateItem) => { return 0; }; -const filterCelebrationFeedItems = (items: CelebrateItem[]) => { +const filterCelebrationFeedItems = ( + items: GetCelebrateFeed_community_celebrationItems_nodes[], +) => { const { completedInteraction, completedStep, @@ -90,10 +99,10 @@ const filterCelebrationFeedItems = (items: CelebrateItem[]) => { } = CELEBRATEABLE_TYPES; return items.filter(item => { - switch (item.celebrateable_type) { + switch (item.celebrateableType) { case completedInteraction: return validInteractionTypes.includes( - `${item.adjective_attribute_value}`, + `${item.adjectiveAttributeValue}`, ); case completedStep: case acceptedCommunityChallenge: From 205f13760c6f864e032d280470d91c0ebe3ee04b Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Thu, 23 Jan 2020 14:55:27 -0500 Subject: [PATCH 03/29] update GroupCelebrate, MemberCelebrate, and GroupUnreadFeed --- package.json | 1 + src/containers/CelebrateFeed/index.tsx | 49 +++++--- src/containers/Groups/GroupCelebrate.tsx | 51 +------- src/containers/Groups/GroupUnreadFeed.tsx | 147 +++++++++------------- src/containers/MemberCelebrate/index.tsx | 101 ++++----------- yarn.lock | 9 +- 6 files changed, 129 insertions(+), 229 deletions(-) diff --git a/package.json b/package.json index 8174b72e1b..c32f5e8f76 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@types/qs": "^6.5.3", "@types/react-native-fbsdk": "^1.0.0", "@types/react-native-push-notification": "^3.0.7", + "@types/react-navigation": "^3.4.0", "@types/uuid": "^3.4.5", "apollo-cache-inmemory": "^1.6.3", "apollo-cache-persist": "^0.1.1", diff --git a/src/containers/CelebrateFeed/index.tsx b/src/containers/CelebrateFeed/index.tsx index 0af3b2672b..a1125d6cb0 100644 --- a/src/containers/CelebrateFeed/index.tsx +++ b/src/containers/CelebrateFeed/index.tsx @@ -17,18 +17,28 @@ import { CelebrateFeedSection, } from '../../selectors/celebration'; import { Organization } from '../../reducers/organizations'; +import { Person } from '../../reducers/people'; import { useRefreshing } from '../../utils/hooks/useRefreshing'; -import { GetCelebrateFeed } from './__generated__/GetCelebrateFeed'; +import { + GetCelebrateFeed, + GetCelebrateFeed_community_celebrationItems_nodes, +} from './__generated__/GetCelebrateFeed'; import styles from './styles'; export const GET_CELEBRATE_FEED = gql` - query GetCelebrateFeed($communityId: [ID!], $celebrateCursor: String) { + query GetCelebrateFeed( + $communityId: ID! + $personId: ID + $hasUnreadComments: Boolean = false + $celebrateCursor: String + ) { community(id: $communityId) { celebrationItems( sortBy: createdAt_ASC first: 25 after: $celebrateCursor + subjectPersonIds: [$personId] ) { nodes { id @@ -56,21 +66,22 @@ export const GET_CELEBRATE_FEED = gql` export interface CelebrateFeedProps { dispatch: ThunkDispatch<{}, {}, AnyAction>; organization: Organization; - refreshCallback: () => void; + person?: Person; itemNamePressable: boolean; - isMember?: boolean; noHeader?: boolean; + onRefetch?: () => void; + onFetchMore?: () => void; onClearNotification?: () => void; - loadMoreItemsCallback: () => void; } const CelebrateFeed = ({ dispatch, organization, - refreshCallback, + person, itemNamePressable, - isMember, noHeader, + onRefetch, + onFetchMore, onClearNotification, }: CelebrateFeedProps) => { const [isListScrolled, setIsListScrolled] = useState(false); @@ -88,7 +99,8 @@ const CelebrateFeed = ({ refetch, } = useQuery(GET_CELEBRATE_FEED, { variables: { - communityId: [organization.id], + communityId: organization.id, + personId: person.id, }, pollInterval: 30000, }); @@ -97,13 +109,17 @@ const CelebrateFeed = ({ const { isRefreshing, refresh } = useRefreshing(refetch); - const handleRefreshing = () => refresh(); + const handleRefreshing = () => { + refresh(); + onRefetch && onRefetch(); + }; const handleOnEndReached = () => { if (isListScrolled && hasNextPage) { fetchMore({ variables: { - communityId: [organization.id], + communityId: organization.id, + personId: person.id, celebrateCursor: endCursor, }, updateQuery: (prev, { fetchMoreResult }) => @@ -127,6 +143,7 @@ const CelebrateFeed = ({ } : prev, }); + onFetchMore && onFetchMore(); setIsListScrolled(false); } }; @@ -151,22 +168,26 @@ const CelebrateFeed = ({ ); - const renderItem = ({ item }: { item: CelebrateItem }) => ( + const renderItem = ({ + item, + }: { + item: GetCelebrateFeed_community_celebrationItems_nodes; + }) => ( ); const renderHeader = () => ( <> - + diff --git a/src/containers/Groups/GroupCelebrate.tsx b/src/containers/Groups/GroupCelebrate.tsx index ac964f3fcc..fc7b21eebe 100644 --- a/src/containers/Groups/GroupCelebrate.tsx +++ b/src/containers/Groups/GroupCelebrate.tsx @@ -1,26 +1,12 @@ -import React, { useState, useEffect } from 'react'; +import React from 'react'; import { connect } from 'react-redux-legacy'; -import moment from 'moment'; import { ThunkDispatch } from 'redux-thunk'; import { AnyAction } from 'redux'; import CelebrateFeed from '../CelebrateFeed'; -import { - getGroupCelebrateFeed, - reloadGroupCelebrateFeed, -} from '../../actions/celebration'; import { refreshCommunity } from '../../actions/organizations'; import { organizationSelector } from '../../selectors/organizations'; -import { - celebrationSelector, - CelebrateItem, -} from '../../selectors/celebration'; -import { - momentUtc, - refresh, - orgIsGlobal, - shouldQueryReportedComments, -} from '../../utils/common'; +import { orgIsGlobal, shouldQueryReportedComments } from '../../utils/common'; import { getReportedComments } from '../../actions/reportComments'; import { orgPermissionSelector } from '../../selectors/people'; import { AuthState } from '../../reducers/auth'; @@ -32,49 +18,24 @@ export interface GroupCelebrateProps { dispatch: ThunkDispatch<{ organizations: OrganizationsState }, {}, AnyAction>; organization: Organization; shouldQueryReport: boolean; - celebrateItems: { id: number; date: string; data: CelebrateItem[] }[]; - pagination: any; } const GroupCelebrate = ({ dispatch, organization, shouldQueryReport, - celebrateItems, - pagination, }: GroupCelebrateProps) => { - const [refreshing, setRefreshing] = useState(false); - - const shouldLoadFeed = () => - !celebrateItems || - celebrateItems.length === 0 || - pagination.page === 0 || - moment().diff(momentUtc(celebrateItems[0].date), 'days', true) > 1; - - const loadItems = () => dispatch(getGroupCelebrateFeed(organization.id)); - - useEffect(() => { - shouldLoadFeed() && loadItems(); - }, []); - - const reloadItems = () => { + const handleRefetch = () => { dispatch(refreshCommunity(organization.id)); shouldQueryReport && dispatch(getReportedComments(organization.id)); - return dispatch(reloadGroupCelebrateFeed(organization.id)); }; - const refreshItems = () => refresh(_, reloadItems); - return ( <> @@ -100,10 +61,6 @@ const mapStateToProps = ( organization, myOrgPermission, ), - celebrateItems: celebrationSelector({ - celebrateItems: organization.celebrateItems || [], - }), - pagination: organization.celebratePagination || {}, }; }; diff --git a/src/containers/Groups/GroupUnreadFeed.tsx b/src/containers/Groups/GroupUnreadFeed.tsx index 5751c341fa..bfc7214e65 100644 --- a/src/containers/Groups/GroupUnreadFeed.tsx +++ b/src/containers/Groups/GroupUnreadFeed.tsx @@ -1,11 +1,14 @@ -import React, { Component } from 'react'; +import React, { Component, useState } from 'react'; import { StatusBar, View } from 'react-native'; import { connect } from 'react-redux-legacy'; -import { withTranslation } from 'react-i18next'; +import { useTranslation } from 'react-i18next'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; import { refresh } from '../../utils/common'; import Header from '../../components/Header'; import { IconButton, Button } from '../../components/common'; +import BackButton from '../BackButton'; import { navigateBack } from '../../actions/navigation'; import { organizationSelector } from '../../selectors/organizations'; import { getGroupCelebrateFeedUnread } from '../../actions/celebration'; @@ -13,6 +16,7 @@ import CelebrateFeed from '../CelebrateFeed'; import theme from '../../theme'; import { celebrationSelector } from '../../selectors/celebration'; import { refreshCommunity } from '../../actions/organizations'; +import { OrganizationsState, Organization } from '../../reducers/organizations'; import { markCommentsRead, markCommentRead, @@ -21,118 +25,81 @@ import Analytics from '../Analytics'; import styles from './styles'; -// @ts-ignore -@withTranslation('groupUnread') -class GroupUnreadFeed extends Component { - state = { refreshing: false, items: [] }; +export interface GroupUnreadFeedProps { + dispatch: ThunkDispatch<{ organizations: OrganizationsState }, {}, AnyAction>; + organization: Organization; + count: number; +} - componentDidMount() { - this.loadItems(); - } +const GroupUnreadFeed = ({ + dispatch, + organization, + count, +}: GroupUnreadFeedProps) => { + const [refreshing, isRefreshing] = useState(false); + const { t } = useTranslation('groupUnread'); - loadItems = async () => { - // @ts-ignore - const { dispatch, organization } = this.props; - dispatch(refreshCommunity(organization.id)); - const { response } = await dispatch( - getGroupCelebrateFeedUnread(organization.id), - ); - const items = celebrationSelector({ - celebrateItems: response || [], - }); - this.setState({ items }); - return items; - }; + const back = () => dispatch(navigateBack()); - refreshItems = () => { - refresh(this, this.loadItems); - }; + const handleRefetch = () => dispatch(refreshCommunity(organization.id)); - markRead = async () => { - // @ts-ignore - const { dispatch, organization } = this.props; + const markAllAsRead = async () => { await dispatch(markCommentsRead(organization.id)); - this.back(); - }; - - // @ts-ignore - clearNotification = async event => { - // @ts-ignore - const { dispatch } = this.props; - await dispatch(markCommentRead(event.id)); - this.loadItems(); + back(); }; - // @ts-ignore - back = () => this.props.dispatch(navigateBack()); + const clearNotification = event => dispatch(markCommentRead(event.id)); - render() { - // @ts-ignore - const { t, organization, count } = this.props; - const { refreshing, items } = this.state; - - return ( - - - -
- } - right={ - @@ -199,13 +196,7 @@ const CelebrateItemContent = ({ }; return ( - + {renderMessage()} {renderChallengeLink()} diff --git a/src/components/CelebrateItemContent/styles.ts b/src/components/CelebrateItemContent/styles.ts index 52a44df08f..aac46d0559 100644 --- a/src/components/CelebrateItemContent/styles.ts +++ b/src/components/CelebrateItemContent/styles.ts @@ -9,9 +9,6 @@ export default StyleSheet.create({ description: { marginTop: 14, }, - fixedHeightDescription: { - height: 70, - }, messageText: { fontSize: 14, lineHeight: 18, diff --git a/src/containers/CelebrateDetailScreen/index.tsx b/src/containers/CelebrateDetailScreen/index.tsx index 1c8dc82bac..1f1cd8ee90 100644 --- a/src/containers/CelebrateDetailScreen/index.tsx +++ b/src/containers/CelebrateDetailScreen/index.tsx @@ -125,7 +125,6 @@ class CelebrateDetailScreen extends Component { ), diff --git a/src/containers/CelebrateFeedHeader/index.tsx b/src/containers/CelebrateFeedHeader/index.tsx index 2e3ebf0209..30e10c678e 100644 --- a/src/containers/CelebrateFeedHeader/index.tsx +++ b/src/containers/CelebrateFeedHeader/index.tsx @@ -1,6 +1,7 @@ -import React, { Component, Fragment } from 'react'; +import React, { Fragment, useEffect } from 'react'; import { connect } from 'react-redux-legacy'; -import PropTypes from 'prop-types'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; import { getReportedComments } from '../../actions/reportComments'; import { Flex } from '../../components/common'; @@ -16,118 +17,114 @@ import { markCommentsRead } from '../../actions/unreadComments'; import UnreadCommentsCard from '../../components/UnreadCommentsCard'; import ReportCommentHeaderCard from '../../components/ReportCommentHeaderCard'; import { GROUP_UNREAD_FEED_SCREEN } from '../Groups/GroupUnreadFeed'; +import { AuthState } from '../../reducers/auth'; +import { OrganizationsState, Organization } from '../../reducers/organizations'; +import { ReportedCommentsState } from '../../reducers/reportedComments'; import styles from './styles'; -class CelebrateFeedHeader extends Component { - componentDidMount() { - const { - // @ts-ignore - dispatch, - // @ts-ignore - organization: { id: orgId }, - // @ts-ignore - shouldQueryReport, - } = this.props; - if (shouldQueryReport) { - dispatch(getReportedComments(orgId)); - } - } - - closeCommentCard = () => { - const { - // @ts-ignore - dispatch, - // @ts-ignore - organization: { id: orgId }, - } = this.props; - dispatch(markCommentsRead(orgId)); +export interface CelebrateFeedHeaderProps { + dispatch: ThunkDispatch<{}, {}, AnyAction>; + organization: Organization; + shouldQueryReport: boolean; + isReportVisible: boolean; + isCommentCardVisible: boolean; + isMember: boolean; + reportedCount: number; + newCommentsCount: number; +} + +const CelebrateFeedHeader = ({ + dispatch, + organization, + shouldQueryReport, + isReportVisible, + isCommentCardVisible, + isMember, + reportedCount, + newCommentsCount, +}: CelebrateFeedHeaderProps) => { + useEffect(() => { + shouldQueryReport && dispatch(getReportedComments(organization.id)); + }, []); + + const closeCommentCard = () => { + dispatch(markCommentsRead(organization.id)); }; - report = () => { - // @ts-ignore - const { dispatch, organization } = this.props; + const report = () => { dispatch(navigatePush(GROUPS_REPORT_SCREEN, { organization })); }; - commentCard = () => { - // @ts-ignore - const { dispatch, organization } = this.props; + const commentCard = () => { dispatch(navigatePush(GROUP_UNREAD_FEED_SCREEN, { organization })); }; - renderCommentCard() { - // @ts-ignore - const { isCommentCardVisible, newCommentsCount } = this.props; + const renderCommentCard = () => { if (!isCommentCardVisible) { return null; } + return ( ); - } + }; - renderReport() { - // @ts-ignore - const { reportedCount, isReportVisible } = this.props; + const renderReport = () => { if (!isReportVisible) { return null; } - return ( - - ); - } - render() { - // @ts-ignore - const { isMember, isReportVisible, isCommentCardVisible } = this.props; - return ( - - {isCommentCardVisible ? null : ( - // @ts-ignore - - )} - {isMember || (!isReportVisible && !isCommentCardVisible) ? null : ( - - {this.renderCommentCard()} - {isReportVisible && isCommentCardVisible ? ( - - ) : null} - {this.renderReport()} - - )} - - ); - } -} + return ; + }; -// @ts-ignore -CelebrateFeedHeader.propTypes = { - organization: PropTypes.object.isRequired, - isMember: PropTypes.bool, + return ( + + {isCommentCardVisible ? null : ( + + )} + {isMember || (!isReportVisible && !isCommentCardVisible) ? null : ( + + {renderCommentCard()} + {isReportVisible && isCommentCardVisible ? ( + + ) : null} + {renderReport()} + + )} + + ); }; export const mapStateToProps = ( - // @ts-ignore - { auth, organizations, reportedComments }, - { organization = {} }, + { + auth, + organizations, + reportedComments, + }: { + auth: AuthState; + organizations: OrganizationsState; + reportedComments: ReportedCommentsState; + }, + { organization }: { organization: Organization }, ) => { const selectorOrg = - // @ts-ignore organizationSelector({ organizations }, { orgId: organization.id }) || organization; - // @ts-ignore - const myOrgPerm = orgPermissionSelector(null, { - person: auth.person, - organization: { id: selectorOrg.id }, - }); - const allReportedComments = reportedComments.all[selectorOrg.id] || []; - const reportedCount = allReportedComments.length; + const myOrgPerm = orgPermissionSelector( + {}, + { + person: auth.person, + organization: { id: selectorOrg.id }, + }, + ); + + const reportedCount = (reportedComments.all[selectorOrg.id] || []).length; const shouldQueryReport = shouldQueryReportedComments(selectorOrg, myOrgPerm); const newCommentsCount = selectorOrg.unread_comments_count; diff --git a/src/containers/CelebrateItemName/index.tsx b/src/containers/CelebrateItemName/index.tsx index 6a13afee2d..16640bf42f 100644 --- a/src/containers/CelebrateItemName/index.tsx +++ b/src/containers/CelebrateItemName/index.tsx @@ -1,47 +1,50 @@ -import React, { Component } from 'react'; -import { withTranslation } from 'react-i18next'; -import PropTypes from 'prop-types'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; import { connect } from 'react-redux-legacy'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; import { Button } from '../../components/common'; import ItemHeaderText from '../../components/ItemHeaderText/index'; import { navToPersonScreen } from '../../actions/person'; +import { GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson } from '../CelebrateFeed/__generated__/GetCelebrateFeed'; +import { Organization } from '../../reducers/organizations'; + +export interface CelebrateItemNameProps { + dispatch: ThunkDispatch<{}, {}, AnyAction>; + name: string | null; + person: GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson | null; + organization: Organization; + pressable: boolean; + customContent?: JSX.Element; +} -// @ts-ignore -@withTranslation('celebrateFeeds') -class CelebrateItemName extends Component { - onPressNameLink = () => { - // @ts-ignore - const { dispatch, person, organization } = this.props; - - dispatch(navToPersonScreen(person, organization)); - }; - - render() { - // @ts-ignore - const { name, t, customContent, pressable } = this.props; - const content = customContent || ( - - ); - - if (!name || !pressable) { - return content; - } - - return ( - - ); +const CelebrateItemName = ({ + dispatch, + name, + person, + organization, + pressable, + customContent, +}: CelebrateItemNameProps) => { + const { t } = useTranslation('celebrateFeeds'); + + const onPressNameLink = () => + person && dispatch(navToPersonScreen(person, organization)); + + const content = customContent || ( + + ); + + if (!name || !pressable) { + return content; } -} -// @ts-ignore -CelebrateItemName.propTypes = { - name: PropTypes.string, - person: PropTypes.object, - organization: PropTypes.object, - pressable: PropTypes.bool, + return ( + + ); }; export default connect()(CelebrateItemName); diff --git a/src/containers/CommentLikeComponent/index.tsx b/src/containers/CommentLikeComponent/index.tsx index 79560a194d..5fe4dd618b 100644 --- a/src/containers/CommentLikeComponent/index.tsx +++ b/src/containers/CommentLikeComponent/index.tsx @@ -1,7 +1,8 @@ -import React, { Component } from 'react'; +import React, { useState } from 'react'; import { Image, View } from 'react-native'; -import PropTypes from 'prop-types'; import { connect } from 'react-redux-legacy'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; import { Text, Button } from '../../components/common'; import { trackActionWithoutData } from '../../actions/analytics'; @@ -10,95 +11,83 @@ import BLUE_HEART from '../../../assets/images/heart-blue.png'; import COMMENTS from '../../../assets/images/comments.png'; import { toggleLike } from '../../actions/celebration'; import { ACTIONS } from '../../constants'; +import { GetCelebrateFeed_community_celebrationItems_nodes } from '../CelebrateFeed/__generated__/GetCelebrateFeed'; +import { AuthState } from '../../reducers/auth'; +import { Organization } from '../../reducers/organizations'; import styles from './styles'; -class CommentLikeComponent extends Component { - state = { isLikeDisabled: false }; +export interface CommentLikeComponentProps { + dispatch: ThunkDispatch<{}, {}, AnyAction>; + organization: Organization; + event: GetCelebrateFeed_community_celebrationItems_nodes; + myId: string; +} + +const CommentLikeComponent = ({ + dispatch, + organization, + event, + myId, +}: CommentLikeComponentProps) => { + const [isLikeDisabled, setIsLikeDisabled] = useState(false); - onPressLikeIcon = async () => { - const { - // @ts-ignore - event: { organization, id, liked }, - // @ts-ignore - dispatch, - } = this.props; + const { id, liked, likesCount, commentsCount, subjectPerson } = event; + const onPressLikeIcon = async () => { try { - this.setState({ isLikeDisabled: true }); + setIsLikeDisabled(true); await dispatch(toggleLike(id, liked, organization && organization.id)); !liked && dispatch(trackActionWithoutData(ACTIONS.ITEM_LIKED)); } finally { - this.setState({ isLikeDisabled: false }); + setIsLikeDisabled(false); } }; - renderCommentIcon() { - const { - // @ts-ignore - event: { comments_count }, - } = this.props; - const displayCommentCount = comments_count > 0; + const renderCommentIcon = () => { + const displayCommentCount = commentsCount > 0; return ( <> - {displayCommentCount ? comments_count : null} + {displayCommentCount ? commentsCount : null} ); - } - - renderLikeIcon() { - // @ts-ignore - const { myId, event } = this.props; - const { subject_person, likes_count, liked } = event; - const { isLikeDisabled } = this.state; + }; + const renderLikeIcon = () => { const displayLikeCount = - likes_count > 0 && subject_person && subject_person.id === myId; + likesCount > 0 && subjectPerson && subjectPerson.id === myId; return ( <> - {displayLikeCount ? likes_count : null} + {displayLikeCount ? likesCount : null} ); - } - - render() { - // @ts-ignore - const { event } = this.props; - const { subject_person } = event; - - return ( - // @ts-ignore - - {subject_person && this.renderCommentIcon()} - {this.renderLikeIcon()} - - ); - } -} + }; -// @ts-ignore -CommentLikeComponent.propTypes = { - event: PropTypes.object.isRequired, - myId: PropTypes.string.isRequired, + return ( + + {subjectPerson && renderCommentIcon()} + {renderLikeIcon()} + + ); }; -// @ts-ignore -const mapStateToProps = ({ auth }) => ({ +const mapStateToProps = ({ auth }: { auth: AuthState }) => ({ myId: auth.person.id, }); + export default connect(mapStateToProps)(CommentLikeComponent); diff --git a/src/containers/CommentLikeComponent/styles.ts b/src/containers/CommentLikeComponent/styles.ts index 31917f3c4b..ff03d78600 100644 --- a/src/containers/CommentLikeComponent/styles.ts +++ b/src/containers/CommentLikeComponent/styles.ts @@ -3,6 +3,11 @@ import { StyleSheet } from 'react-native'; import theme from '../../theme'; export default StyleSheet.create({ + container: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end', + }, icon: { height: 24, width: 24, diff --git a/src/containers/Groups/OnboardingCard.tsx b/src/containers/Groups/OnboardingCard.tsx index 3e22cb8851..8b14a116bd 100644 --- a/src/containers/Groups/OnboardingCard.tsx +++ b/src/containers/Groups/OnboardingCard.tsx @@ -1,8 +1,9 @@ -import React, { Component } from 'react'; +import React from 'react'; import { Image } from 'react-native'; import { connect } from 'react-redux-legacy'; -import { withTranslation } from 'react-i18next'; -import PropTypes from 'prop-types'; +import { useTranslation } from 'react-i18next'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; import HEARTS from '../../../assets/images/celebrateHearts.png'; import TARGET from '../../../assets/images/challengeTarget.png'; @@ -14,15 +15,39 @@ import STEPS from '../../../assets/images/footprints.png'; import { Flex, Text, Card, IconButton } from '../../components/common'; import { removeGroupOnboardingCard } from '../../actions/swipe'; import theme from '../../theme'; +import { SwipeState } from '../../reducers/swipe'; import styles from './styles'; -// @ts-ignore -@withTranslation('groupOnboardingCard') -class OnboardingCard extends Component { - getImage() { - // @ts-ignore - switch (this.props.type) { +export enum GROUP_ONBOARDING_TYPES { + celebrate, + challenges, + members, + impact, + contacts, + surveys, + steps, +} + +export interface OnboardingCardProps { + dispatch: ThunkDispatch<{}, {}, AnyAction>; + type: GROUP_ONBOARDING_TYPES; + groupOnboarding: { [key: string]: boolean }; +} + +const OnboardingCard = ({ + dispatch, + type, + groupOnboarding, +}: OnboardingCardProps) => { + const { t } = useTranslation('groupOnboardingCard'); + + if (!groupOnboarding[type]) { + return null; + } + + const getImage = () => { + switch (type) { case GROUP_ONBOARDING_TYPES.celebrate: return HEARTS; case GROUP_ONBOARDING_TYPES.challenges: @@ -40,77 +65,50 @@ class OnboardingCard extends Component { default: return null; } - } - - handlePress = () => { - // @ts-ignore - const { type, dispatch } = this.props; - dispatch(removeGroupOnboardingCard(type)); }; - render() { - // @ts-ignore - const { t, type, groupOnboarding } = this.props; - if (!groupOnboarding[type]) { - return null; - } - return ( - - - - - {t(`${type}Header`)} - - - {t(`${type}Description`)} - - - - - - - ); - } -} - -export const GROUP_ONBOARDING_TYPES = { - celebrate: 'celebrate', - challenges: 'challenges', - members: 'members', - impact: 'impact', - contacts: 'contacts', - surveys: 'surveys', - steps: 'steps', -}; + const handlePress = () => dispatch(removeGroupOnboardingCard(type)); -// @ts-ignore -OnboardingCard.propTypes = { - type: PropTypes.oneOf(Object.keys(GROUP_ONBOARDING_TYPES)).isRequired, + return ( + + + + + {t(`${type}Header`)} + + + {t(`${type}Description`)} + + + + + + + ); }; -// @ts-ignore -const mapStateToProps = ({ swipe }) => ({ +const mapStateToProps = ({ swipe }: { swipe: SwipeState }) => ({ groupOnboarding: swipe.groupOnboarding || {}, }); From eb04c217e902f7b8a6d5f28beb9f4842ddbf4b15 Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Mon, 27 Jan 2020 10:08:29 -0500 Subject: [PATCH 07/29] apply types to other screens --- src/components/CelebrateItem/index.tsx | 7 +- .../CelebrateDetailScreen/index.tsx | 243 ++++++++---------- src/containers/CommentsList/index.tsx | 182 ++++++------- .../Groups/EditStoryScreen/index.tsx | 11 +- .../Groups/ShareStoryInput/index.tsx | 4 +- .../Groups/ShareStoryScreen/index.tsx | 2 +- src/utils/hooks/useKeyboardListeners.ts | 35 ++- 7 files changed, 234 insertions(+), 250 deletions(-) diff --git a/src/components/CelebrateItem/index.tsx b/src/components/CelebrateItem/index.tsx index 165936085c..75b4b74b07 100644 --- a/src/components/CelebrateItem/index.tsx +++ b/src/components/CelebrateItem/index.tsx @@ -19,6 +19,7 @@ import { CELEBRATE_EDIT_STORY_SCREEN } from '../../containers/Groups/EditStorySc import { orgIsGlobal } from '../../utils/common'; import { AuthState } from '../../reducers/auth'; import { Person } from '../../reducers/people'; +import { Organization } from '../../reducers/organizations'; import { CELEBRATEABLE_TYPES } from '../../constants'; import { GetCelebrateFeed_community_celebrationItems_nodes } from '../../containers/CelebrateFeed/__generated__/GetCelebrateFeed'; @@ -49,7 +50,7 @@ export const REPORT_STORY = gql` export interface CelebrateItemProps { dispatch: ThunkDispatch<{}, {}, AnyAction>; event: GetCelebrateFeed_community_celebrationItems_nodes; - organization: object; + organization: Organization; namePressable: boolean; onClearNotification?: ( event: GetCelebrateFeed_community_celebrationItems_nodes, @@ -84,7 +85,9 @@ const CelebrateItem = ({ ); const handlePress = () => - dispatch(navigatePush(CELEBRATE_DETAIL_SCREEN, { event })); + dispatch( + navigatePush(CELEBRATE_DETAIL_SCREEN, { event, orgId: organization.id }), + ); const clearNotification = () => onClearNotification && onClearNotification(event); diff --git a/src/containers/CelebrateDetailScreen/index.tsx b/src/containers/CelebrateDetailScreen/index.tsx index 1f1cd8ee90..0e2ae3167c 100644 --- a/src/containers/CelebrateDetailScreen/index.tsx +++ b/src/containers/CelebrateDetailScreen/index.tsx @@ -1,10 +1,10 @@ -import React, { Component } from 'react'; -import { Image, View, SafeAreaView, StatusBar } from 'react-native'; +import React, { useRef } from 'react'; +import { Image, View, SafeAreaView, StatusBar, FlatList } from 'react-native'; import { connect } from 'react-redux-legacy'; -import PropTypes from 'prop-types'; +import { AnyAction } from 'redux'; +import { ThunkDispatch } from 'redux-thunk'; import CommentLikeComponent from '../CommentLikeComponent'; -import { celebrationItemSelector } from '../../selectors/celebration'; import { organizationSelector } from '../../selectors/organizations'; import CommentsList from '../CommentsList'; import BackButton from '../BackButton'; @@ -12,7 +12,6 @@ import CelebrateCommentBox from '../../components/CelebrateCommentBox'; import theme from '../../theme'; import TRAILS1 from '../../../assets/images/Trailss.png'; import TRAILS2 from '../../../assets/images/TrailGrey.png'; -import { refresh, keyboardShow } from '../../utils/common'; import { reloadCelebrateComments } from '../../actions/celebrateComments'; import { celebrateCommentsSelector } from '../../selectors/celebrateComments'; import CardTime from '../../components/CardTime'; @@ -20,166 +19,138 @@ import CelebrateItemName from '../CelebrateItemName'; import CelebrateItemContent from '../../components/CelebrateItemContent'; import { RefreshControl } from '../../components/common'; import Analytics from '../Analytics'; +import { GetCelebrateFeed_community_celebrationItems_nodes } from '../CelebrateFeed/__generated__/GetCelebrateFeed'; +import { Organization, OrganizationsState } from '../../reducers/organizations'; +import { + CelebrateCommentsState, + CelebrateComment, +} from '../../reducers/celebrateComments'; +import { useKeyboardListeners } from '../../utils/hooks/useKeyboardListeners'; +import { useRefreshing } from '../../utils/hooks/useRefreshing'; import styles from './styles'; -class CelebrateDetailScreen extends Component { - state = { refreshing: false }; - - componentDidMount() { - // @ts-ignore - this.keyboardShowListener = keyboardShow(this.keyboardShow, 'did'); - } - - componentWillUnmount() { - // @ts-ignore - this.keyboardShowListener.remove(); - } +export interface CelebrateDetailScreenProps { + dispatch: ThunkDispatch<{}, {}, AnyAction>; + event: GetCelebrateFeed_community_celebrationItems_nodes; + organization: Organization; + celebrateComments: { comments: CelebrateComment[] }; + editingCommentId: string; +} - keyboardShow = () => this.scrollToFocusedRef(); +const CelebrateDetailScreen = ({ + dispatch, + event, + organization, + celebrateComments, + editingCommentId, +}: CelebrateDetailScreenProps) => { + const listRef = useRef>(null); - // @ts-ignore - scrollToEnd = () => this.listRef && this.listRef.scrollToEnd(); + const scrollToEnd = () => listRef && listRef.scrollToEnd(); - scrollToFocusedRef = () => { - const { - // @ts-ignore - celebrateComments: { comments }, - // @ts-ignore - editingCommentId, - } = this.props; + const scrollToFocusedRef = () => { if (editingCommentId) { - // @ts-ignore - const index = comments.findIndex(c => c.id === editingCommentId); + const index = celebrateComments.comments.findIndex( + c => c.id === editingCommentId, + ); if (index >= 0) { - // @ts-ignore - this.listRef && this.listRef.scrollToIndex({ index, viewPosition: 1 }); + listRef && listRef.scrollToIndex({ index, viewPosition: 1 }); return; } } - this.scrollToEnd(); + scrollToEnd(); }; - refreshComments = () => { - // @ts-ignore - const { dispatch, event } = this.props; + useKeyboardListeners({ onShow: () => scrollToFocusedRef() }); + + const refreshComments = () => { return dispatch(reloadCelebrateComments(event)); }; - handleRefresh = () => refresh(this, this.refreshComments); - - renderHeader = () => { - // @ts-ignore - const { event, organization } = this.props; - return ( - - - - // @ts-ignore - - // @ts-ignore - - - - - // @ts-ignore - - ( + + + + + + + + + - - ); - }; - - renderCommentsList = () => { - // @ts-ignore - const { event, organization } = this.props; - const { refreshing } = this.state; - return ( - - - - (this.listRef = c), - refreshControl: ( - - ), - ListHeaderComponent: () => ( - - ), - }} - /> - ); - }; - - renderCommentBox = () => { - // @ts-ignore - const { event } = this.props; - return ( - - ); - }; - - render() { - return ( - - - {this.renderHeader()} - {this.renderCommentsList()} - {this.renderCommentBox()} - - ); - } -} - -// @ts-ignore -CelebrateDetailScreen.propTypes = { - event: PropTypes.object.isRequired, + + ); + + const renderCommentsList = () => ( + + + + + ), + ListHeaderComponent: () => ( + + ), + }} + /> + + ); + + const renderCommentBox = () => ( + + ); + + return ( + + + {renderHeader()} + {renderCommentsList()} + {renderCommentBox()} + + ); }; const mapStateToProps = ( - // @ts-ignore - { organizations, celebrateComments }, + { + organizations, + celebrateComments, + }: { + organizations: OrganizationsState; + celebrateComments: CelebrateCommentsState; + }, { navigation: { state: { - // @ts-ignore - params: { event }, + params: { event, orgId }, }, }, - }, + }: // eslint-disable-next-line @typescript-eslint/no-explicit-any + any, ) => ({ - event: - celebrationItemSelector( - { organizations }, - { eventId: event.id, organizationId: event.organization.id }, - ) || event, - organization: organizationSelector( - { organizations }, - { orgId: event.organization.id }, - ), + organization: organizationSelector({ organizations }, { orgId }), celebrateComments: celebrateCommentsSelector( { celebrateComments }, { eventId: event.id }, diff --git a/src/containers/CommentsList/index.tsx b/src/containers/CommentsList/index.tsx index 3bce58fcd5..fe91198e88 100644 --- a/src/containers/CommentsList/index.tsx +++ b/src/containers/CommentsList/index.tsx @@ -1,8 +1,10 @@ -import React, { Component } from 'react'; +import React, { Component, useEffect } from 'react'; import { connect } from 'react-redux-legacy'; import PropTypes from 'prop-types'; import { Alert, FlatList } from 'react-native'; -import { withTranslation } from 'react-i18next'; +import { ThunkDispatch } from 'redux-thunk'; +import { AnyAction } from 'redux'; +import { useTranslation } from 'react-i18next'; import { celebrateCommentsSelector } from '../../selectors/celebrateComments'; import { @@ -17,37 +19,60 @@ import LoadMore from '../../components/LoadMore'; import { keyExtractorId, isOwner } from '../../utils/common'; import CommentItem from '../CommentItem'; import { orgPermissionSelector } from '../../selectors/people'; +import { AuthState } from '../../reducers/auth'; +import { + CelebrateCommentsState, + CelebrateComment, +} from '../../reducers/celebrateComments'; +import { Organization } from '../../reducers/organizations'; +import { Person } from '../../reducers/people'; +import { GetCelebrateFeed_community_celebrationItems_nodes } from '../CelebrateFeed/__generated__/GetCelebrateFeed'; import styles from './styles'; -// @ts-ignore -@withTranslation('commentsList') -class CommentsList extends Component { - componentDidMount() { - // @ts-ignore - const { dispatch, event } = this.props; +export interface CommentsListProps { + dispatch: ThunkDispatch<{ auth: AuthState }, {}, AnyAction>; + event: GetCelebrateFeed_community_celebrationItems_nodes; + organization: Organization; + me: Person; + celebrateComments: { comments: CelebrateComment[]; pagination: any }; + listProps: { [key: string]: any }; +} +const CommentsList = ({ + dispatch, + event, + organization, + me, + celebrateComments, + listProps, +}: CommentsListProps) => { + const { t } = useTranslation('commentsList'); + + useEffect(() => { dispatch(reloadCelebrateComments(event)); dispatch(resetCelebrateEditingComment()); - } - - handleLoadMore = () => { - // @ts-ignore - const { dispatch, event } = this.props; + }, []); + const handleLoadMore = () => { dispatch(getCelebrateCommentsNextPage(event)); }; - // @ts-ignore - handleEdit = item => { - // @ts-ignore - this.props.dispatch(setCelebrateEditingComment(item.id)); + const handleEdit = (item: CelebrateComment) => { + dispatch(setCelebrateEditingComment(item.id)); }; - // @ts-ignore - alert = ({ title, message, actionText, action }) => { - // @ts-ignore - const { t } = this.props; + const alert = ({ + title, + message, + actionText, + action, + }: { + title: string; + message: string; + actionText: string; + action: () => void; + }) => { Alert.alert(t(title), t(message), [ { text: t('cancel'), @@ -60,72 +85,57 @@ class CommentsList extends Component { ]); }; - // @ts-ignore - handleDelete = item => { - // @ts-ignore - const { dispatch, event } = this.props; - - this.alert({ + const handleDelete = (item: CelebrateComment) => { + alert({ title: 'deletePostHeader', message: 'deleteAreYouSure', actionText: 'deletePost', action: () => { - dispatch(deleteCelebrateComment(event.organization.id, event, item)); + dispatch(deleteCelebrateComment(organization.id, event, item)); }, }); }; - // @ts-ignore - handleReport = item => { - // @ts-ignore - const { dispatch, event } = this.props; - this.alert({ + const handleReport = (item: CelebrateComment) => { + alert({ title: 'reportToOwnerHeader', message: 'reportAreYouSure', actionText: 'reportPost', action: () => { - dispatch(reportComment(event.organization.id, item)); + dispatch(reportComment(organization.id, item)); }, }); }; - // @ts-ignore - menuActions = item => { - const { - // @ts-ignore - t, - // @ts-ignore - event: { organization }, - // @ts-ignore - me, - } = this.props; - + const menuActions = (item: CelebrateComment) => { const actions = []; const deleteAction = { text: t('deletePost'), - onPress: () => this.handleDelete(item), + onPress: () => handleDelete(item), destructive: true, }; if (me.id === item.person.id) { actions.push({ text: t('editPost'), - onPress: () => this.handleEdit(item), + onPress: () => handleEdit(item), }); actions.push(deleteAction); } else { const orgPermission = - // @ts-ignore - orgPermissionSelector(null, { - person: me, - organization, - }) || {}; + orgPermissionSelector( + {}, + { + person: me, + organization, + }, + ) || {}; if (isOwner(orgPermission)) { actions.push(deleteAction); } else { actions.push({ text: t('reportToOwner'), - onPress: () => this.handleReport(item), + onPress: () => handleReport(item), }); } } @@ -133,51 +143,41 @@ class CommentsList extends Component { return actions; }; - // @ts-ignore - renderItem = ({ item }) => ( + const renderItem = ({ item }: { item: CelebrateComment }) => ( ); - render() { - const { - // @ts-ignore - listProps, - // @ts-ignore - celebrateComments: { comments, pagination } = {}, - } = this.props; - const { list, listContent } = styles; - - return ( - - } - bounces={false} - {...listProps} - /> - ); - } -} - -// @ts-ignore -CommentsList.propTypes = { - event: PropTypes.object.isRequired, + const { comments, pagination } = celebrateComments; + const { list, listContent } = styles; + + return ( + + } + bounces={false} + {...listProps} + /> + ); }; -// @ts-ignore -const mapStateToProps = ({ auth, celebrateComments }, { event }) => ({ +const mapStateToProps = ( + { + auth, + celebrateComments, + }: { auth: AuthState; celebrateComments: CelebrateCommentsState }, + { event }: { event: GetCelebrateFeed_community_celebrationItems_nodes }, +) => ({ me: auth.person, celebrateComments: celebrateCommentsSelector( { celebrateComments }, diff --git a/src/containers/Groups/EditStoryScreen/index.tsx b/src/containers/Groups/EditStoryScreen/index.tsx index 7d3be541ff..a8c5fd7577 100644 --- a/src/containers/Groups/EditStoryScreen/index.tsx +++ b/src/containers/Groups/EditStoryScreen/index.tsx @@ -14,8 +14,8 @@ import Header from '../../../components/Header'; import { navigateBack } from '../../../actions/navigation'; import BackButton from '../../BackButton'; import theme from '../../../theme'; -import { Event } from '../../../components/CelebrateItem'; import { useAnalytics } from '../../../utils/hooks/useAnalytics'; +import { GetCelebrateFeed_community_celebrationItems_nodes } from '../../CelebrateFeed/__generated__/GetCelebrateFeed'; import styles from './styles'; import { UpdateStory, UpdateStoryVariables } from './__generated__/UpdateStory'; @@ -39,13 +39,16 @@ const EditStoryScreen = ({ dispatch }: EditStoryProps) => { const { t } = useTranslation('editStoryScreen'); const { container, backButton, textInput } = styles; const onRefresh: () => Promise = useNavigationParam('onRefresh'); - const { object_description, celebrateable_id }: Event = useNavigationParam( + const { + objectDescription, + celebrateableId, + }: GetCelebrateFeed_community_celebrationItems_nodes = useNavigationParam( 'celebrationItem', ); const [updateStory] = useMutation( UPDATE_STORY, ); - const [story, changeStory] = useState(object_description); + const [story, changeStory] = useState(objectDescription || undefined); const saveStory = async () => { if (!story) { @@ -53,7 +56,7 @@ const EditStoryScreen = ({ dispatch }: EditStoryProps) => { } Keyboard.dismiss(); await updateStory({ - variables: { input: { id: celebrateable_id, content: story } }, + variables: { input: { id: celebrateableId, content: story } }, }); onRefresh(); diff --git a/src/containers/Groups/ShareStoryInput/index.tsx b/src/containers/Groups/ShareStoryInput/index.tsx index c6ea3743da..115b2cf058 100644 --- a/src/containers/Groups/ShareStoryInput/index.tsx +++ b/src/containers/Groups/ShareStoryInput/index.tsx @@ -31,8 +31,8 @@ const ShareStoryInput = ({ return dispatch( navigatePush(CELEBRATE_SHARE_STORY_SCREEN, { organization, - onComplete: async () => { - await refreshItems(); + onComplete: () => { + refreshItems(); dispatch(navigateBack()); }, }), diff --git a/src/containers/Groups/ShareStoryScreen/index.tsx b/src/containers/Groups/ShareStoryScreen/index.tsx index 8523c3e24b..1846bd5833 100644 --- a/src/containers/Groups/ShareStoryScreen/index.tsx +++ b/src/containers/Groups/ShareStoryScreen/index.tsx @@ -34,7 +34,7 @@ const ShareStoryScreen = () => { const { t } = useTranslation('shareAStoryScreen'); const { container, backButton, textInput } = styles; const [story, changeStory] = useState(''); - const onComplete: () => Promise = useNavigationParam('onComplete'); + const onComplete: () => void = useNavigationParam('onComplete'); const organization: Organization = useNavigationParam('organization'); const [createStory] = useMutation( CREATE_A_STORY, diff --git a/src/utils/hooks/useKeyboardListeners.ts b/src/utils/hooks/useKeyboardListeners.ts index e5b288f9e2..28d7b590e7 100644 --- a/src/utils/hooks/useKeyboardListeners.ts +++ b/src/utils/hooks/useKeyboardListeners.ts @@ -3,23 +3,30 @@ import { Keyboard } from 'react-native'; import { isAndroid } from '../common'; -export const useKeyboardListeners = ( - onShow: () => void, - onHide: () => void, -) => { +export const useKeyboardListeners = ({ + onShow, + onHide, +}: { + onShow?: () => void; + onHide?: () => void; +}) => { useEffect(() => { - const keyboardShowListener = Keyboard.addListener( - isAndroid ? 'keyboardDidShow' : 'keyboardWillShow', - onShow, - ); - const keyboardHideListener = Keyboard.addListener( - isAndroid ? 'keyboardDidHide' : 'keyboardWillHide', - onHide, - ); + const keyboardShowListener = onShow + ? Keyboard.addListener( + isAndroid ? 'keyboardDidShow' : 'keyboardWillShow', + onShow, + ) + : null; + const keyboardHideListener = onHide + ? Keyboard.addListener( + isAndroid ? 'keyboardDidHide' : 'keyboardWillHide', + onHide, + ) + : null; return () => { - keyboardShowListener.remove(); - keyboardHideListener.remove(); + keyboardShowListener && keyboardShowListener.remove(); + keyboardHideListener && keyboardHideListener.remove(); }; }, [onShow, onHide]); }; From 832b0eabcde443f46c372b9bcbea396fe704b918 Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Mon, 27 Jan 2020 10:11:01 -0500 Subject: [PATCH 08/29] undo import --- package.json | 1 - yarn.lock | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/package.json b/package.json index c32f5e8f76..8174b72e1b 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "@types/qs": "^6.5.3", "@types/react-native-fbsdk": "^1.0.0", "@types/react-native-push-notification": "^3.0.7", - "@types/react-navigation": "^3.4.0", "@types/uuid": "^3.4.5", "apollo-cache-inmemory": "^1.6.3", "apollo-cache-persist": "^0.1.1", diff --git a/yarn.lock b/yarn.lock index 6f73978ff4..bca37dfbb2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1702,13 +1702,6 @@ "@types/prop-types" "*" "@types/react" "*" -"@types/react-navigation@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@types/react-navigation/-/react-navigation-3.4.0.tgz#d610d13c9162312079a8ca102660143f07432cbf" - integrity sha512-Y7F5zU8BTBK8tEOvUqgvwvPZ7+9vnc2UI1vHwJ/9ZJG98TntNv04GWa6lrn4MA4149pqw6cyNw/V49Yd2osAFQ== - dependencies: - react-navigation "*" - "@types/react-redux-legacy@npm:@types/react-redux@^7.1.5", "@types/react-redux@^7.1.5": version "7.1.5" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.5.tgz#c7a528d538969250347aa53c52241051cf886bd3" @@ -8844,7 +8837,7 @@ react-navigation-tabs@^2.5.6: react-native-safe-area-view "^0.14.6" react-native-tab-view "^2.9.0" -react-navigation@*, react-navigation@^4.0.10: +react-navigation@^4.0.10: version "4.0.10" resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-4.0.10.tgz#ddf41134600689d6ba99e35dd22ba1f664f91e5c" integrity sha512-7PqvmsdQ7HIyxPUMYbd9Uq//VoMdniEOLAOSvIhb/ExtbAt/1INSjUF+RiMWOMCWLTCNvNPRvTz7xy7qwWureg== From 42e2bde4737effc9a429fc741cd404b94ba80c7e Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Mon, 27 Jan 2020 11:48:58 -0500 Subject: [PATCH 09/29] updates to reducers, selectors, and hooks --- src/containers/Auth/SignInScreen/index.tsx | 5 ++++- src/reducers/celebrateComments.ts | 16 ++++++++++++---- src/selectors/celebration.ts | 21 --------------------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/containers/Auth/SignInScreen/index.tsx b/src/containers/Auth/SignInScreen/index.tsx index 76b3a6870b..db2050faf1 100644 --- a/src/containers/Auth/SignInScreen/index.tsx +++ b/src/containers/Auth/SignInScreen/index.tsx @@ -58,7 +58,10 @@ const SignInScreen = ({ const [isLoading, setIsLoading] = useState(false); const [showLogo, setShowLogo] = useState(true); - useKeyboardListeners(() => setShowLogo(false), () => setShowLogo(true)); + useKeyboardListeners({ + onShow: () => setShowLogo(false), + onHide: () => setShowLogo(true), + }); const handleForgotPassword = async () => { // @ts-ignore diff --git a/src/reducers/celebrateComments.ts b/src/reducers/celebrateComments.ts index e9552da23d..7f1ca2568a 100644 --- a/src/reducers/celebrateComments.ts +++ b/src/reducers/celebrateComments.ts @@ -10,10 +10,18 @@ import { getPagination } from '../utils/common'; import { PaginationObject } from './organizations'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type Event = any; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type CelebrateComment = any; +export interface CelebrateEvent { + id: string; + updated_at: string; + created_at: string; + comments: CelebrateComment[]; +} +export interface CelebrateComment { + id: string; + updated_at: string; + created_at: string; + content: string; +} export interface CelebrateCommentsState { all: { diff --git a/src/selectors/celebration.ts b/src/selectors/celebration.ts index 52f95c6751..56512714ea 100644 --- a/src/selectors/celebration.ts +++ b/src/selectors/celebration.ts @@ -11,27 +11,6 @@ export interface CelebrateFeedSection { data: GetCelebrateFeed_community_celebrationItems_nodes[]; } -export const celebrationItemSelector = createSelector( - ({ organizations }: { organizations: OrganizationsState }) => - organizations.all, - ( - _: { organizations: OrganizationsState }, - { eventId }: { eventId: string; organizationId: string }, - ) => eventId, - ( - _: { organizations: OrganizationsState }, - { organizationId }: { eventId: string; organizationId: string }, - ) => organizationId, - (orgs, eventId, organizationId) => { - const { celebrateItems } = orgs.find(({ id }) => id === organizationId); - - return ( - celebrateItems && - celebrateItems.find(({ id }: CelebrateItem) => id === eventId) - ); - }, -); - export const celebrationSelector = createSelector( ({ celebrateItems, From e3d6a64bb6b8d23d12520b27d0aca971efe030c8 Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Mon, 27 Jan 2020 14:48:38 -0500 Subject: [PATCH 10/29] more updates --- src/components/CelebrateCommentBox/index.tsx | 15 +- src/components/CelebrateItem/index.tsx | 1 + .../CelebrateDetailScreen/index.tsx | 7 +- src/containers/CommentItem/index.tsx | 183 ++++++++---------- src/containers/CommentsList/index.tsx | 5 +- src/reducers/celebrateComments.ts | 2 + src/selectors/celebration.ts | 1 - 7 files changed, 94 insertions(+), 120 deletions(-) diff --git a/src/components/CelebrateCommentBox/index.tsx b/src/components/CelebrateCommentBox/index.tsx index 0f5fd6a40a..fcc1d1cc78 100644 --- a/src/components/CelebrateCommentBox/index.tsx +++ b/src/components/CelebrateCommentBox/index.tsx @@ -9,15 +9,14 @@ import { resetCelebrateEditingComment, updateCelebrateComment, } from '../../actions/celebrateComments'; -import { celebrationItemSelector } from '../../selectors/celebration'; import { celebrateCommentsCommentSelector } from '../../selectors/celebrateComments'; -import { OrganizationsState } from '../../reducers/organizations'; import { CelebrateCommentsState } from '../../reducers/celebrateComments'; +import { GetCelebrateFeed_community_celebrationItems_nodes } from '../../containers/CelebrateFeed/__generated__/GetCelebrateFeed'; import styles from './styles'; interface CelebrateCommentBoxProps { - event: object; + event: GetCelebrateFeed_community_celebrationItems_nodes; editingComment?: object; onAddComplete?: () => void; dispatch: ThunkDispatch<{}, {}, AnyAction>; @@ -61,24 +60,16 @@ const CelebrateCommentBox = ({ }; const mapStateToProps = ( { - organizations, celebrateComments, }: { - organizations: OrganizationsState; celebrateComments: CelebrateCommentsState; }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - { event }: any, + { event }: { event: GetCelebrateFeed_community_celebrationItems_nodes }, ) => ({ editingComment: celebrateCommentsCommentSelector( { celebrateComments }, { eventId: event.id, commentId: celebrateComments.editingCommentId }, ), - event: - celebrationItemSelector( - { organizations }, - { eventId: event.id, organizationId: event.organization.id }, - ) || event, }); export default connect(mapStateToProps)(CelebrateCommentBox); diff --git a/src/components/CelebrateItem/index.tsx b/src/components/CelebrateItem/index.tsx index 75b4b74b07..cbc70499a5 100644 --- a/src/components/CelebrateItem/index.tsx +++ b/src/components/CelebrateItem/index.tsx @@ -201,6 +201,7 @@ const CelebrateItem = ({ { const listRef = useRef>(null); - const scrollToEnd = () => listRef && listRef.scrollToEnd(); + const scrollToEnd = () => listRef.current && listRef.current.scrollToEnd(); const scrollToFocusedRef = () => { if (editingCommentId) { @@ -55,7 +55,8 @@ const CelebrateDetailScreen = ({ c => c.id === editingCommentId, ); if (index >= 0) { - listRef && listRef.scrollToIndex({ index, viewPosition: 1 }); + listRef.current && + listRef.current.scrollToIndex({ index, viewPosition: 1 }); return; } } diff --git a/src/containers/CommentItem/index.tsx b/src/containers/CommentItem/index.tsx index ae26c0375c..52dfbb5f33 100644 --- a/src/containers/CommentItem/index.tsx +++ b/src/containers/CommentItem/index.tsx @@ -1,31 +1,51 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; +import React from 'react'; import { View } from 'react-native'; import { connect } from 'react-redux-legacy'; +import { useNavigationParam } from 'react-navigation-hooks'; import { Text, Flex } from '../../components/common'; import CardTime from '../../components/CardTime'; import PopupMenu from '../../components/PopupMenu'; import CelebrateItemName from '../../containers/CelebrateItemName'; import { DateConstants } from '../../components/DateComponent'; +import { AuthState } from '../../reducers/auth'; +import { + CelebrateCommentsState, + CelebrateComment, +} from '../../reducers/celebrateComments'; +import { Organization } from '../../reducers/organizations'; +import { Person } from '../../reducers/people'; import styles from './styles'; -class CommentItem extends Component { - renderContent = () => { - const { - // @ts-ignore - item: { content, person }, - // @ts-ignore - me, - // @ts-ignore - isReported, - } = this.props; - const { itemStyle, myStyle, text, myText } = styles; +export interface CommentItemProps { + me: Person; + isEditing: boolean; +} + +const CommentItem = ({ me, isEditing }: CommentItemProps) => { + const item: CelebrateComment = useNavigationParam('item'); + const organization: Organization = useNavigationParam('organization'); + const isReported: boolean = useNavigationParam('isReported') || false; + const menuActions: { + [key: string]: { text: string; onPress: () => void; destructive?: boolean }; + } = useNavigationParam('menuActions'); - const isMine = person.id === me.id; - const isMineNotReported = isMine && !isReported; + const { content, person, created_at } = item; + const { + itemStyle, + myStyle, + text, + myText, + content: contentStyle, + editingStyle, + name: nameStyle, + } = styles; + const name = `${person.first_name} ${person.last_name}`; + const isMine = person.id === me.id; + const isMineNotReported = isMine && !isReported; + const renderContent = () => { return ( {content} @@ -33,97 +53,56 @@ class CommentItem extends Component { ); }; - render() { - const { - // @ts-ignore - item: { created_at, person }, - // @ts-ignore - organization, - // @ts-ignore - me, - // @ts-ignore - isEditing, - // @ts-ignore - isReported, - // @ts-ignore - menuActions, - } = this.props; - const { content: contentStyle, editingStyle, name: nameStyle } = styles; - - const name = `${person.first_name} ${person.last_name}`; - const isMine = person.id === me.id; - const isMineNotReported = isMine && !isReported; - - return ( - // Android needs the collapsable property to use '.measure' properly within the - // https://github.com/facebook/react-native/issues/3282#issuecomment-201934117 - - - {isMineNotReported ? ( - - ) : ( - {name}} - /> - )} - - - - {isMineNotReported ? : null} - {menuActions ? ( - - {this.renderContent()} - - ) : ( - this.renderContent() - )} - {!isMineNotReported ? : null} - - - ); - } -} - -// @ts-ignore -CommentItem.propTypes = { - item: PropTypes.object.isRequired, - organization: PropTypes.object, - isReported: PropTypes.bool, - menuActions: PropTypes.arrayOf( - PropTypes.shape({ - text: PropTypes.string.isRequired, - onPress: PropTypes.func.isRequired, - }), - ), + return ( + // Android needs the collapsable property to use '.measure' properly within the + // https://github.com/facebook/react-native/issues/3282#issuecomment-201934117 + + + {isMineNotReported ? ( + + ) : ( + {name}} + /> + )} + + + + {isMineNotReported ? : null} + {menuActions ? ( + + {renderContent()} + + ) : ( + renderContent() + )} + {!isMineNotReported ? : null} + + + ); }; + const mapStateToProps = ( - // @ts-ignore - { auth, celebrateComments: { editingCommentId } }, - // @ts-ignore - { item }, + { + auth, + celebrateComments: { editingCommentId }, + }: { auth: AuthState; celebrateComments: CelebrateCommentsState }, + { item }: { item: CelebrateComment }, ) => ({ me: auth.person, isEditing: editingCommentId === item.id, }); -export default connect( - mapStateToProps, - undefined, - undefined, - { withRef: true }, -)(CommentItem); +export default connect(mapStateToProps)(CommentItem); diff --git a/src/containers/CommentsList/index.tsx b/src/containers/CommentsList/index.tsx index fe91198e88..326d566407 100644 --- a/src/containers/CommentsList/index.tsx +++ b/src/containers/CommentsList/index.tsx @@ -1,6 +1,5 @@ -import React, { Component, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { connect } from 'react-redux-legacy'; -import PropTypes from 'prop-types'; import { Alert, FlatList } from 'react-native'; import { ThunkDispatch } from 'redux-thunk'; import { AnyAction } from 'redux'; @@ -35,7 +34,9 @@ export interface CommentsListProps { event: GetCelebrateFeed_community_celebrationItems_nodes; organization: Organization; me: Person; + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ celebrateComments: { comments: CelebrateComment[]; pagination: any }; + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ listProps: { [key: string]: any }; } diff --git a/src/reducers/celebrateComments.ts b/src/reducers/celebrateComments.ts index 7f1ca2568a..cf8af39ec6 100644 --- a/src/reducers/celebrateComments.ts +++ b/src/reducers/celebrateComments.ts @@ -9,6 +9,7 @@ import { REQUESTS } from '../api/routes'; import { getPagination } from '../utils/common'; import { PaginationObject } from './organizations'; +import { Person } from './people'; export interface CelebrateEvent { id: string; @@ -21,6 +22,7 @@ export interface CelebrateComment { updated_at: string; created_at: string; content: string; + person: Person; } export interface CelebrateCommentsState { diff --git a/src/selectors/celebration.ts b/src/selectors/celebration.ts index 56512714ea..89fe6f7f88 100644 --- a/src/selectors/celebration.ts +++ b/src/selectors/celebration.ts @@ -2,7 +2,6 @@ import { createSelector } from 'reselect'; import { momentUtc } from '../utils/common'; import { CELEBRATEABLE_TYPES } from '../constants'; -import { OrganizationsState } from '../reducers/organizations'; import { GetCelebrateFeed_community_celebrationItems_nodes } from '../containers/CelebrateFeed/__generated__/GetCelebrateFeed'; export interface CelebrateFeedSection { From 592bbfdbf0a40ee75f210991bdd054897a53ad93 Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Tue, 28 Jan 2020 17:14:31 -0500 Subject: [PATCH 11/29] start tests --- __mock__/globalSetup.ts | 3 + package.json | 1 + .../CelebrateFeed/__tests__/CelebrateFeed.tsx | 294 +- .../__snapshots__/CelebrateFeed.tsx.snap | 4433 ++++++++++++++++- src/containers/CelebrateFeed/index.tsx | 8 +- .../__snapshots__/celebration.ts.snap | 384 +- src/selectors/__tests__/celebration.ts | 140 +- testUtils/globalMocks.ts | 14 + 8 files changed, 4853 insertions(+), 424 deletions(-) create mode 100644 __mock__/globalSetup.ts diff --git a/__mock__/globalSetup.ts b/__mock__/globalSetup.ts new file mode 100644 index 0000000000..67ca0db633 --- /dev/null +++ b/__mock__/globalSetup.ts @@ -0,0 +1,3 @@ +export default () => { + process.env.TZ = 'UTC'; +}; diff --git a/package.json b/package.json index 8174b72e1b..a1fdf50fdd 100644 --- a/package.json +++ b/package.json @@ -180,6 +180,7 @@ "/__mock__/resetGlobalMockSeeds.ts", "/__mock__/apolloHooks.ts" ], + "globalSetup": "/__mock__/globalSetup.ts", "snapshotSerializers": [ "enzyme-to-json/serializer" ], diff --git a/src/containers/CelebrateFeed/__tests__/CelebrateFeed.tsx b/src/containers/CelebrateFeed/__tests__/CelebrateFeed.tsx index 13a18560ba..f0c564ddbf 100644 --- a/src/containers/CelebrateFeed/__tests__/CelebrateFeed.tsx +++ b/src/containers/CelebrateFeed/__tests__/CelebrateFeed.tsx @@ -1,139 +1,227 @@ import React from 'react'; -import configureStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import { MockList } from 'graphql-tools'; +import { flushMicrotasksQueue } from 'react-native-testing-library'; +import { useQuery } from '@apollo/react-hooks'; import { navigatePush } from '../../../actions/navigation'; -import { renderShallow } from '../../../../testUtils'; -import { ACCEPTED_STEP } from '../../../constants'; +import { renderWithContext } from '../../../../testUtils'; +import { organizationSelector } from '../../../selectors/organizations'; +import { Organization } from '../../../reducers/organizations'; +import { Person } from '../../../reducers/people'; -import CelebrateFeed from '..'; +import CelebrateFeed, { GET_CELEBRATE_FEED } from '..'; jest.mock('../../../actions/navigation'); -jest.mock('../../../actions/celebration'); +jest.mock('../../../selectors/organizations'); +jest.mock('../../../components/common', () => ({ + DateComponent: 'DateComponent', +})); +jest.mock('../../../components/CelebrateItem', () => 'CelebrateItem'); +jest.mock('../../Groups/ShareStoryInput', () => 'ShareStoryInput'); +jest.mock('../../CelebrateFeedHeader', () => 'CelebrateFeedHeader'); const myId = '123'; -const organization = { id: '456' }; -const store = configureStore([thunk])({ auth: { person: { id: myId } } }); - -const celebrationItems = [ - { - date: '2018-03-01 12:00:00', - data: [ - { - id: '1', - subject_person_name: 'Roge Dog', - celebrateable_type: ACCEPTED_STEP, - likes_count: 0, - adjective_attribute_value: '2', - changed_attribute_value: '2018-03-01 12:00:00', - }, - { - id: '2', - subject_person_name: 'DG With me?', - celebrateable_type: 'interaction', - likes_count: 0, - adjective_attribute_value: '4', - changed_attribute_value: '2018-03-01 12:00:00', - }, - ], - }, - { - date: '2018-01-01 12:00:00', - data: [ - { - id: '4', - subject_person_name: 'Roge Dog', - celebrateable_type: ACCEPTED_STEP, - likes_count: 11, - adjective_attribute_value: '1', - changed_attribute_value: '2018-01-01 12:00:00', - }, - { - id: '3', - subject_person_name: 'DG With me?', - celebrateable_type: 'interaction', - likes_count: 42, - adjective_attribute_value: '5', - changed_attribute_value: '2018-01-01 12:00:00', - }, - ], - }, -]; +const organization: Organization = { id: '456' }; +const person: Person = { id: '789' }; const navigatePushResult = { type: 'navigated' }; -// @ts-ignore -let component; - -// @ts-ignore -navigatePush.mockReturnValue(dispatch => dispatch(navigatePushResult)); - beforeEach(() => { - component = renderShallow( - // @ts-ignore - , - store, + (navigatePush as jest.Mock).mockReturnValue(navigatePushResult); + ((organizationSelector as unknown) as jest.Mock).mockReturnValue( + organization, ); + jest.useFakeTimers(); }); -describe('Member Feed rendering', () => { - it('renders correctly for member feed', () => { - // @ts-ignore - expect(component).toMatchSnapshot(); +it('renders empty correctly', () => { + renderWithContext( + , + { + initialState: { + auth: { person: { id: myId } }, + organizations: { all: [organization] }, + reportedComments: { all: { [organization.id]: [] } }, + swipe: { groupOnboarding: {} }, + }, + mocks: { + CommunityCelebrationItemConnection: () => ({ + nodes: () => new MockList(10), + }), + }, + }, + ).snapshot(); +}); + +it('renders with celebration items correctly', async () => { + const { snapshot } = renderWithContext( + , + { + initialState: { + auth: { person: { id: myId } }, + organizations: { all: [organization] }, + reportedComments: { all: { [organization.id]: [] } }, + swipe: { groupOnboarding: {} }, + }, + mocks: { + CommunityCelebrationItemConnection: () => ({ + nodes: () => new MockList(10), + }), + }, + }, + ); + + await flushMicrotasksQueue(); + snapshot(); + expect(useQuery).toHaveBeenCalledWith(GET_CELEBRATE_FEED, { + pollInterval: 30000, + variables: { + communityId: organization.id, + hasUnreadComments: undefined, + personIds: undefined, + }, }); }); -describe('no header rendering', () => { - it('renders correctly for no header', () => { - component = renderShallow( +describe('renders for member', () => { + it('renders correctly', async () => { + const { snapshot } = renderWithContext( , - store, + { + initialState: { + auth: { person: { id: myId } }, + organizations: { all: [organization] }, + reportedComments: { all: { [organization.id]: [] } }, + swipe: { groupOnboarding: {} }, + }, + mocks: { + CommunityCelebrationItemConnection: () => ({ + nodes: () => new MockList(10), + }), + }, + }, ); - expect(component).toMatchSnapshot(); + + await flushMicrotasksQueue(); + snapshot(); + expect(useQuery).toHaveBeenCalledWith(GET_CELEBRATE_FEED, { + pollInterval: 30000, + variables: { + communityId: organization.id, + hasUnreadComments: undefined, + personIds: [person.id], + }, + }); }); -}); -describe('renders with clear notification set', () => { - it('renders correctly with clear notification set', () => { - component = renderShallow( + it('renders without header', async () => { + const { snapshot } = renderWithContext( , - store, + { + initialState: { + auth: { person: { id: myId } }, + organizations: { all: [organization] }, + reportedComments: { all: { [organization.id]: [] } }, + swipe: { groupOnboarding: {} }, + }, + mocks: { + CommunityCelebrationItemConnection: () => ({ + nodes: () => new MockList(10), + }), + }, + }, ); - expect(component).toMatchSnapshot(); + + await flushMicrotasksQueue(); + snapshot(); + expect(useQuery).toHaveBeenCalledWith(GET_CELEBRATE_FEED, { + pollInterval: 30000, + variables: { + communityId: organization.id, + hasUnreadComments: undefined, + personIds: [person.id], + }, + }); }); }); -it('renders section header', () => { - // @ts-ignore - const renderedItem = component - .instance() - .renderSectionHeader({ section: { date: '2018-08-13T12:00:00.000Z' } }); - expect(renderedItem).toMatchSnapshot(); -}); +describe('renders with clear notification', () => { + it('renders correctly', async () => { + const { snapshot } = renderWithContext( + , + { + initialState: { + auth: { person: { id: myId } }, + organizations: { all: [organization] }, + reportedComments: { all: { [organization.id]: [] } }, + swipe: { groupOnboarding: {} }, + }, + mocks: { + CommunityCelebrationItemConnection: () => ({ + nodes: () => new MockList(10), + }), + }, + }, + ); -describe('item', () => { - it('renders correctly', () => { - // @ts-ignore - const renderedItem = component - .instance() - .renderItem({ item: celebrationItems[0] }); - expect(renderedItem).toMatchSnapshot(); + await flushMicrotasksQueue(); + snapshot(); + expect(useQuery).toHaveBeenCalledWith(GET_CELEBRATE_FEED, { + pollInterval: 30000, + variables: { + communityId: organization.id, + hasUnreadComments: undefined, + personIds: undefined, + }, + }); }); }); -it('renderHeader match snapshot', () => { - // @ts-ignore - const header = component.instance().renderHeader(); - expect(header).toMatchSnapshot(); +describe('renders for Unread Comments', () => { + it('renders correctly', async () => { + const { snapshot } = renderWithContext( + , + { + initialState: { + auth: { person: { id: myId } }, + organizations: { all: [organization] }, + reportedComments: { all: { [organization.id]: [] } }, + swipe: { groupOnboarding: {} }, + }, + mocks: { + CommunityCelebrationItemConnection: () => ({ + nodes: () => new MockList(10), + }), + }, + }, + ); + + await flushMicrotasksQueue(); + snapshot(); + expect(useQuery).toHaveBeenCalledWith(GET_CELEBRATE_FEED, { + pollInterval: 30000, + variables: { + communityId: organization.id, + hasUnreadComments: true, + personIds: undefined, + }, + }); + }); }); diff --git a/src/containers/CelebrateFeed/__tests__/__snapshots__/CelebrateFeed.tsx.snap b/src/containers/CelebrateFeed/__tests__/__snapshots__/CelebrateFeed.tsx.snap index 70b6a0cc5d..45bb09130f 100644 --- a/src/containers/CelebrateFeed/__tests__/__snapshots__/CelebrateFeed.tsx.snap +++ b/src/containers/CelebrateFeed/__tests__/__snapshots__/CelebrateFeed.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Member Feed rendering renders correctly for member feed 1`] = ` - + } + refreshing={false} + renderItem={[Function]} + renderSectionHeader={[Function]} + scrollEventThrottle={50} + sections={Array []} + stickyHeaderIndices={Array []} + stickySectionHeadersEnabled={true} + style={ + Object { + "backgroundColor": "#ECEEF2", + } + } + updateCellsBatchingPeriod={50} + windowSize={21} +> + + + + + + + + +`; + +exports[`renders for Unread Comments renders correctly 1`] = ` + + } + refreshing={false} + renderItem={[Function]} + renderSectionHeader={[Function]} + scrollEventThrottle={50} + sections={ + Array [ + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sit vitae soluta", + "adjectiveAttributeValue": "sint non voluptates", + "celebrateableId": "5", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "ut ullam quos", + "changedAttributeValue": "2019-02-10T23:08:19:60", + "commentsCount": 58438, + "id": "4", + "liked": false, + "likesCount": 56591, + "objectDescription": "sunt laborum ratione", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Vern", + "id": "6", + "lastName": "McKenzie", + }, + "subjectPersonName": "Zola Corkery", + }, + ], + "date": "2019-02-10T23:08:19:60", + "id": 0, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quasi ipsum rem", + "adjectiveAttributeValue": "eos quod recusandae", + "celebrateableId": "26", + "celebrateableType": "story", + "changedAttributeName": "consectetur optio laudantium", + "changedAttributeValue": "2018-01-20T22:18:35:43", + "commentsCount": 6600, + "id": "25", + "liked": false, + "likesCount": 75546, + "objectDescription": "molestias facere quia", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Therese", + "id": "27", + "lastName": "Beatty", + }, + "subjectPersonName": "Hipolito Connelly", + }, + ], + "date": "2018-01-20T22:18:35:43", + "id": 1, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ullam minima ducimus", + "adjectiveAttributeValue": "temporibus modi aut", + "celebrateableId": "2", + "celebrateableType": "accepted_challenge", + "changedAttributeName": "architecto ducimus totam", + "changedAttributeValue": "2017-01-05T11:40:00:73", + "commentsCount": 90859, + "id": "1", + "liked": false, + "likesCount": 29361, + "objectDescription": "ut quis sed", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Breana", + "id": "3", + "lastName": "Ledner", + }, + "subjectPersonName": "Torey Abbott", + }, + ], + "date": "2017-01-05T11:40:00:73", + "id": 2, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quaerat cumque incidunt", + "adjectiveAttributeValue": "aut provident esse", + "celebrateableId": "8", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "hic eligendi quos", + "changedAttributeValue": "2016-07-31T16:52:49:08", + "commentsCount": 41417, + "id": "7", + "liked": true, + "likesCount": 4995, + "objectDescription": "voluptas sed quae", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Malcolm", + "id": "9", + "lastName": "Connelly", + }, + "subjectPersonName": "Grace Dibbert", + }, + ], + "date": "2016-07-31T16:52:49:08", + "id": 3, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sint autem rerum", + "adjectiveAttributeValue": "doloremque officia aut", + "celebrateableId": "11", + "celebrateableType": "story", + "changedAttributeName": "ut ut eos", + "changedAttributeValue": "2014-08-26T07:39:14:97", + "commentsCount": 44798, + "id": "10", + "liked": false, + "likesCount": 89213, + "objectDescription": "consequatur vel in", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kaley", + "id": "12", + "lastName": "Cummerata", + }, + "subjectPersonName": "Marcellus Hyatt", + }, + ], + "date": "2014-08-26T07:39:14:97", + "id": 4, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "non aut rerum", + "adjectiveAttributeValue": "impedit ex rem", + "celebrateableId": "23", + "celebrateableType": "organization", + "changedAttributeName": "voluptates voluptas fuga", + "changedAttributeValue": "2014-06-14T18:46:15:61", + "commentsCount": 46739, + "id": "22", + "liked": false, + "likesCount": 26900, + "objectDescription": "non fugiat eligendi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kathryne", + "id": "24", + "lastName": "Zieme", + }, + "subjectPersonName": "Tatyana Johns", + }, + ], + "date": "2014-06-14T18:46:15:61", + "id": 5, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ex culpa earum", + "adjectiveAttributeValue": "voluptate vel labore", + "celebrateableId": "20", + "celebrateableType": "organization", + "changedAttributeName": "omnis ut est", + "changedAttributeValue": "2013-05-02T19:02:46:48", + "commentsCount": 57367, + "id": "19", + "liked": false, + "likesCount": 287, + "objectDescription": "est et sequi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Ericka", + "id": "21", + "lastName": "Mayert", + }, + "subjectPersonName": "Daphney Balistreri", + }, + ], + "date": "2013-05-02T19:02:46:48", + "id": 6, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "et molestiae ea", + "adjectiveAttributeValue": "ut sunt placeat", + "celebrateableId": "14", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "quidem est consequuntur", + "changedAttributeValue": "2013-03-09T22:46:17:95", + "commentsCount": 88330, + "id": "13", + "liked": true, + "likesCount": 62367, + "objectDescription": "est placeat ex", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Favian", + "id": "15", + "lastName": "Ruecker", + }, + "subjectPersonName": "Roscoe Johnson", + }, + ], + "date": "2013-03-09T22:46:17:95", + "id": 7, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "enim ex eveniet", + "adjectiveAttributeValue": "facere molestiae aut", + "celebrateableId": "17", + "celebrateableType": "organization", + "changedAttributeName": "delectus aut nam", + "changedAttributeValue": "2011-04-05T20:54:44:94", + "commentsCount": 49810, + "id": "16", + "liked": true, + "likesCount": 7379, + "objectDescription": "fugit repellendus hic", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Anissa", + "id": "18", + "lastName": "Kirlin", + }, + "subjectPersonName": "Judge Doyle", + }, + ], + "date": "2011-04-05T20:54:44:94", + "id": 8, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quo occaecati quia", + "adjectiveAttributeValue": "ipsum sit qui", + "celebrateableId": "29", + "celebrateableType": "organizational_permission", + "changedAttributeName": "accusantium odit doloremque", + "changedAttributeValue": "2010-05-11T20:17:10:67", + "commentsCount": 50981, + "id": "28", + "liked": false, + "likesCount": 10213, + "objectDescription": "eos quis ut", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Dario", + "id": "30", + "lastName": "Lueilwitz", + }, + "subjectPersonName": "Orlando Schmidt", + }, + ], + "date": "2010-05-11T20:17:10:67", + "id": 9, + }, + ] + } + stickyHeaderIndices={ + Array [ + 1, + 4, + 7, + 10, + ] + } + stickySectionHeadersEnabled={true} + style={ + Object { + "backgroundColor": "#ECEEF2", + } + } + updateCellsBatchingPeriod={50} + windowSize={21} +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`renders for member renders correctly 1`] = ` + + } + refreshing={false} + renderItem={[Function]} + renderSectionHeader={[Function]} + scrollEventThrottle={50} + sections={ + Array [ + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sit vitae soluta", + "adjectiveAttributeValue": "sint non voluptates", + "celebrateableId": "5", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "ut ullam quos", + "changedAttributeValue": "2019-02-10T23:08:19:60", + "commentsCount": 58438, + "id": "4", + "liked": false, + "likesCount": 56591, + "objectDescription": "sunt laborum ratione", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Vern", + "id": "6", + "lastName": "McKenzie", + }, + "subjectPersonName": "Zola Corkery", + }, + ], + "date": "2019-02-10T23:08:19:60", + "id": 0, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quasi ipsum rem", + "adjectiveAttributeValue": "eos quod recusandae", + "celebrateableId": "26", + "celebrateableType": "story", + "changedAttributeName": "consectetur optio laudantium", + "changedAttributeValue": "2018-01-20T22:18:35:43", + "commentsCount": 6600, + "id": "25", + "liked": false, + "likesCount": 75546, + "objectDescription": "molestias facere quia", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Therese", + "id": "27", + "lastName": "Beatty", + }, + "subjectPersonName": "Hipolito Connelly", + }, + ], + "date": "2018-01-20T22:18:35:43", + "id": 1, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ullam minima ducimus", + "adjectiveAttributeValue": "temporibus modi aut", + "celebrateableId": "2", + "celebrateableType": "accepted_challenge", + "changedAttributeName": "architecto ducimus totam", + "changedAttributeValue": "2017-01-05T11:40:00:73", + "commentsCount": 90859, + "id": "1", + "liked": false, + "likesCount": 29361, + "objectDescription": "ut quis sed", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Breana", + "id": "3", + "lastName": "Ledner", + }, + "subjectPersonName": "Torey Abbott", + }, + ], + "date": "2017-01-05T11:40:00:73", + "id": 2, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quaerat cumque incidunt", + "adjectiveAttributeValue": "aut provident esse", + "celebrateableId": "8", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "hic eligendi quos", + "changedAttributeValue": "2016-07-31T16:52:49:08", + "commentsCount": 41417, + "id": "7", + "liked": true, + "likesCount": 4995, + "objectDescription": "voluptas sed quae", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Malcolm", + "id": "9", + "lastName": "Connelly", + }, + "subjectPersonName": "Grace Dibbert", + }, + ], + "date": "2016-07-31T16:52:49:08", + "id": 3, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sint autem rerum", + "adjectiveAttributeValue": "doloremque officia aut", + "celebrateableId": "11", + "celebrateableType": "story", + "changedAttributeName": "ut ut eos", + "changedAttributeValue": "2014-08-26T07:39:14:97", + "commentsCount": 44798, + "id": "10", + "liked": false, + "likesCount": 89213, + "objectDescription": "consequatur vel in", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kaley", + "id": "12", + "lastName": "Cummerata", + }, + "subjectPersonName": "Marcellus Hyatt", + }, + ], + "date": "2014-08-26T07:39:14:97", + "id": 4, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "non aut rerum", + "adjectiveAttributeValue": "impedit ex rem", + "celebrateableId": "23", + "celebrateableType": "organization", + "changedAttributeName": "voluptates voluptas fuga", + "changedAttributeValue": "2014-06-14T18:46:15:61", + "commentsCount": 46739, + "id": "22", + "liked": false, + "likesCount": 26900, + "objectDescription": "non fugiat eligendi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kathryne", + "id": "24", + "lastName": "Zieme", + }, + "subjectPersonName": "Tatyana Johns", + }, + ], + "date": "2014-06-14T18:46:15:61", + "id": 5, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ex culpa earum", + "adjectiveAttributeValue": "voluptate vel labore", + "celebrateableId": "20", + "celebrateableType": "organization", + "changedAttributeName": "omnis ut est", + "changedAttributeValue": "2013-05-02T19:02:46:48", + "commentsCount": 57367, + "id": "19", + "liked": false, + "likesCount": 287, + "objectDescription": "est et sequi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Ericka", + "id": "21", + "lastName": "Mayert", + }, + "subjectPersonName": "Daphney Balistreri", + }, + ], + "date": "2013-05-02T19:02:46:48", + "id": 6, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "et molestiae ea", + "adjectiveAttributeValue": "ut sunt placeat", + "celebrateableId": "14", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "quidem est consequuntur", + "changedAttributeValue": "2013-03-09T22:46:17:95", + "commentsCount": 88330, + "id": "13", + "liked": true, + "likesCount": 62367, + "objectDescription": "est placeat ex", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Favian", + "id": "15", + "lastName": "Ruecker", + }, + "subjectPersonName": "Roscoe Johnson", + }, + ], + "date": "2013-03-09T22:46:17:95", + "id": 7, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "enim ex eveniet", + "adjectiveAttributeValue": "facere molestiae aut", + "celebrateableId": "17", + "celebrateableType": "organization", + "changedAttributeName": "delectus aut nam", + "changedAttributeValue": "2011-04-05T20:54:44:94", + "commentsCount": 49810, + "id": "16", + "liked": true, + "likesCount": 7379, + "objectDescription": "fugit repellendus hic", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Anissa", + "id": "18", + "lastName": "Kirlin", + }, + "subjectPersonName": "Judge Doyle", + }, + ], + "date": "2011-04-05T20:54:44:94", + "id": 8, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quo occaecati quia", + "adjectiveAttributeValue": "ipsum sit qui", + "celebrateableId": "29", + "celebrateableType": "organizational_permission", + "changedAttributeName": "accusantium odit doloremque", + "changedAttributeValue": "2010-05-11T20:17:10:67", + "commentsCount": 50981, + "id": "28", + "liked": false, + "likesCount": 10213, + "objectDescription": "eos quis ut", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Dario", + "id": "30", + "lastName": "Lueilwitz", + }, + "subjectPersonName": "Orlando Schmidt", + }, + ], + "date": "2010-05-11T20:17:10:67", + "id": 9, + }, + ] + } + stickyHeaderIndices={ + Array [ + 1, + 4, + 7, + 10, + ] + } + stickySectionHeadersEnabled={true} + style={ + Object { + "backgroundColor": "#ECEEF2", + } + } + updateCellsBatchingPeriod={50} + windowSize={21} +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`renders for member renders without header 1`] = ` + + } refreshing={false} renderItem={[Function]} renderSectionHeader={[Function]} @@ -32,113 +2133,845 @@ exports[`Member Feed rendering renders correctly for member feed 1`] = ` Object { "data": Array [ Object { - "adjective_attribute_value": "2", - "celebrateable_type": "accepted_challenge", - "changed_attribute_value": "2018-03-01 12:00:00", - "id": "1", - "likes_count": 0, - "subject_person_name": "Roge Dog", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sit vitae soluta", + "adjectiveAttributeValue": "sint non voluptates", + "celebrateableId": "5", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "ut ullam quos", + "changedAttributeValue": "2019-02-10T23:08:19:60", + "commentsCount": 58438, + "id": "4", + "liked": false, + "likesCount": 56591, + "objectDescription": "sunt laborum ratione", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Vern", + "id": "6", + "lastName": "McKenzie", + }, + "subjectPersonName": "Zola Corkery", + }, + ], + "date": "2019-02-10T23:08:19:60", + "id": 0, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quasi ipsum rem", + "adjectiveAttributeValue": "eos quod recusandae", + "celebrateableId": "26", + "celebrateableType": "story", + "changedAttributeName": "consectetur optio laudantium", + "changedAttributeValue": "2018-01-20T22:18:35:43", + "commentsCount": 6600, + "id": "25", + "liked": false, + "likesCount": 75546, + "objectDescription": "molestias facere quia", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Therese", + "id": "27", + "lastName": "Beatty", + }, + "subjectPersonName": "Hipolito Connelly", + }, + ], + "date": "2018-01-20T22:18:35:43", + "id": 1, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ullam minima ducimus", + "adjectiveAttributeValue": "temporibus modi aut", + "celebrateableId": "2", + "celebrateableType": "accepted_challenge", + "changedAttributeName": "architecto ducimus totam", + "changedAttributeValue": "2017-01-05T11:40:00:73", + "commentsCount": 90859, + "id": "1", + "liked": false, + "likesCount": 29361, + "objectDescription": "ut quis sed", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Breana", + "id": "3", + "lastName": "Ledner", + }, + "subjectPersonName": "Torey Abbott", + }, + ], + "date": "2017-01-05T11:40:00:73", + "id": 2, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quaerat cumque incidunt", + "adjectiveAttributeValue": "aut provident esse", + "celebrateableId": "8", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "hic eligendi quos", + "changedAttributeValue": "2016-07-31T16:52:49:08", + "commentsCount": 41417, + "id": "7", + "liked": true, + "likesCount": 4995, + "objectDescription": "voluptas sed quae", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Malcolm", + "id": "9", + "lastName": "Connelly", + }, + "subjectPersonName": "Grace Dibbert", + }, + ], + "date": "2016-07-31T16:52:49:08", + "id": 3, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sint autem rerum", + "adjectiveAttributeValue": "doloremque officia aut", + "celebrateableId": "11", + "celebrateableType": "story", + "changedAttributeName": "ut ut eos", + "changedAttributeValue": "2014-08-26T07:39:14:97", + "commentsCount": 44798, + "id": "10", + "liked": false, + "likesCount": 89213, + "objectDescription": "consequatur vel in", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kaley", + "id": "12", + "lastName": "Cummerata", + }, + "subjectPersonName": "Marcellus Hyatt", + }, + ], + "date": "2014-08-26T07:39:14:97", + "id": 4, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "non aut rerum", + "adjectiveAttributeValue": "impedit ex rem", + "celebrateableId": "23", + "celebrateableType": "organization", + "changedAttributeName": "voluptates voluptas fuga", + "changedAttributeValue": "2014-06-14T18:46:15:61", + "commentsCount": 46739, + "id": "22", + "liked": false, + "likesCount": 26900, + "objectDescription": "non fugiat eligendi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kathryne", + "id": "24", + "lastName": "Zieme", + }, + "subjectPersonName": "Tatyana Johns", + }, + ], + "date": "2014-06-14T18:46:15:61", + "id": 5, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ex culpa earum", + "adjectiveAttributeValue": "voluptate vel labore", + "celebrateableId": "20", + "celebrateableType": "organization", + "changedAttributeName": "omnis ut est", + "changedAttributeValue": "2013-05-02T19:02:46:48", + "commentsCount": 57367, + "id": "19", + "liked": false, + "likesCount": 287, + "objectDescription": "est et sequi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Ericka", + "id": "21", + "lastName": "Mayert", + }, + "subjectPersonName": "Daphney Balistreri", + }, + ], + "date": "2013-05-02T19:02:46:48", + "id": 6, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "et molestiae ea", + "adjectiveAttributeValue": "ut sunt placeat", + "celebrateableId": "14", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "quidem est consequuntur", + "changedAttributeValue": "2013-03-09T22:46:17:95", + "commentsCount": 88330, + "id": "13", + "liked": true, + "likesCount": 62367, + "objectDescription": "est placeat ex", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Favian", + "id": "15", + "lastName": "Ruecker", + }, + "subjectPersonName": "Roscoe Johnson", + }, + ], + "date": "2013-03-09T22:46:17:95", + "id": 7, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "enim ex eveniet", + "adjectiveAttributeValue": "facere molestiae aut", + "celebrateableId": "17", + "celebrateableType": "organization", + "changedAttributeName": "delectus aut nam", + "changedAttributeValue": "2011-04-05T20:54:44:94", + "commentsCount": 49810, + "id": "16", + "liked": true, + "likesCount": 7379, + "objectDescription": "fugit repellendus hic", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Anissa", + "id": "18", + "lastName": "Kirlin", + }, + "subjectPersonName": "Judge Doyle", + }, + ], + "date": "2011-04-05T20:54:44:94", + "id": 8, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quo occaecati quia", + "adjectiveAttributeValue": "ipsum sit qui", + "celebrateableId": "29", + "celebrateableType": "organizational_permission", + "changedAttributeName": "accusantium odit doloremque", + "changedAttributeValue": "2010-05-11T20:17:10:67", + "commentsCount": 50981, + "id": "28", + "liked": false, + "likesCount": 10213, + "objectDescription": "eos quis ut", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Dario", + "id": "30", + "lastName": "Lueilwitz", + }, + "subjectPersonName": "Orlando Schmidt", + }, + ], + "date": "2010-05-11T20:17:10:67", + "id": 9, + }, + ] + } + stickyHeaderIndices={ + Array [ + 0, + 3, + 6, + 9, + ] + } + stickySectionHeadersEnabled={true} + style={ + Object { + "backgroundColor": "#ECEEF2", + } + } + updateCellsBatchingPeriod={50} + windowSize={21} +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`renders with celebration items correctly 1`] = ` + -`; - -exports[`item renders correctly 1`] = ` - -`; - -exports[`no header rendering renders correctly for no header 1`] = ` - + } refreshing={false} renderItem={[Function]} renderSectionHeader={[Function]} @@ -148,47 +2981,283 @@ exports[`no header rendering renders correctly for no header 1`] = ` Object { "data": Array [ Object { - "adjective_attribute_value": "2", - "celebrateable_type": "accepted_challenge", - "changed_attribute_value": "2018-03-01 12:00:00", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sit vitae soluta", + "adjectiveAttributeValue": "sint non voluptates", + "celebrateableId": "5", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "ut ullam quos", + "changedAttributeValue": "2019-02-10T23:08:19:60", + "commentsCount": 58438, + "id": "4", + "liked": false, + "likesCount": 56591, + "objectDescription": "sunt laborum ratione", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Vern", + "id": "6", + "lastName": "McKenzie", + }, + "subjectPersonName": "Zola Corkery", + }, + ], + "date": "2019-02-10T23:08:19:60", + "id": 0, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quasi ipsum rem", + "adjectiveAttributeValue": "eos quod recusandae", + "celebrateableId": "26", + "celebrateableType": "story", + "changedAttributeName": "consectetur optio laudantium", + "changedAttributeValue": "2018-01-20T22:18:35:43", + "commentsCount": 6600, + "id": "25", + "liked": false, + "likesCount": 75546, + "objectDescription": "molestias facere quia", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Therese", + "id": "27", + "lastName": "Beatty", + }, + "subjectPersonName": "Hipolito Connelly", + }, + ], + "date": "2018-01-20T22:18:35:43", + "id": 1, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ullam minima ducimus", + "adjectiveAttributeValue": "temporibus modi aut", + "celebrateableId": "2", + "celebrateableType": "accepted_challenge", + "changedAttributeName": "architecto ducimus totam", + "changedAttributeValue": "2017-01-05T11:40:00:73", + "commentsCount": 90859, "id": "1", - "likes_count": 0, - "subject_person_name": "Roge Dog", + "liked": false, + "likesCount": 29361, + "objectDescription": "ut quis sed", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Breana", + "id": "3", + "lastName": "Ledner", + }, + "subjectPersonName": "Torey Abbott", }, + ], + "date": "2017-01-05T11:40:00:73", + "id": 2, + }, + Object { + "data": Array [ Object { - "adjective_attribute_value": "4", - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-03-01 12:00:00", - "id": "2", - "likes_count": 0, - "subject_person_name": "DG With me?", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quaerat cumque incidunt", + "adjectiveAttributeValue": "aut provident esse", + "celebrateableId": "8", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "hic eligendi quos", + "changedAttributeValue": "2016-07-31T16:52:49:08", + "commentsCount": 41417, + "id": "7", + "liked": true, + "likesCount": 4995, + "objectDescription": "voluptas sed quae", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Malcolm", + "id": "9", + "lastName": "Connelly", + }, + "subjectPersonName": "Grace Dibbert", }, ], - "date": "2018-03-01 12:00:00", + "date": "2016-07-31T16:52:49:08", + "id": 3, }, Object { "data": Array [ Object { - "adjective_attribute_value": "1", - "celebrateable_type": "accepted_challenge", - "changed_attribute_value": "2018-01-01 12:00:00", - "id": "4", - "likes_count": 11, - "subject_person_name": "Roge Dog", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sint autem rerum", + "adjectiveAttributeValue": "doloremque officia aut", + "celebrateableId": "11", + "celebrateableType": "story", + "changedAttributeName": "ut ut eos", + "changedAttributeValue": "2014-08-26T07:39:14:97", + "commentsCount": 44798, + "id": "10", + "liked": false, + "likesCount": 89213, + "objectDescription": "consequatur vel in", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kaley", + "id": "12", + "lastName": "Cummerata", + }, + "subjectPersonName": "Marcellus Hyatt", + }, + ], + "date": "2014-08-26T07:39:14:97", + "id": 4, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "non aut rerum", + "adjectiveAttributeValue": "impedit ex rem", + "celebrateableId": "23", + "celebrateableType": "organization", + "changedAttributeName": "voluptates voluptas fuga", + "changedAttributeValue": "2014-06-14T18:46:15:61", + "commentsCount": 46739, + "id": "22", + "liked": false, + "likesCount": 26900, + "objectDescription": "non fugiat eligendi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kathryne", + "id": "24", + "lastName": "Zieme", + }, + "subjectPersonName": "Tatyana Johns", + }, + ], + "date": "2014-06-14T18:46:15:61", + "id": 5, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ex culpa earum", + "adjectiveAttributeValue": "voluptate vel labore", + "celebrateableId": "20", + "celebrateableType": "organization", + "changedAttributeName": "omnis ut est", + "changedAttributeValue": "2013-05-02T19:02:46:48", + "commentsCount": 57367, + "id": "19", + "liked": false, + "likesCount": 287, + "objectDescription": "est et sequi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Ericka", + "id": "21", + "lastName": "Mayert", + }, + "subjectPersonName": "Daphney Balistreri", + }, + ], + "date": "2013-05-02T19:02:46:48", + "id": 6, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "et molestiae ea", + "adjectiveAttributeValue": "ut sunt placeat", + "celebrateableId": "14", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "quidem est consequuntur", + "changedAttributeValue": "2013-03-09T22:46:17:95", + "commentsCount": 88330, + "id": "13", + "liked": true, + "likesCount": 62367, + "objectDescription": "est placeat ex", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Favian", + "id": "15", + "lastName": "Ruecker", + }, + "subjectPersonName": "Roscoe Johnson", + }, + ], + "date": "2013-03-09T22:46:17:95", + "id": 7, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "enim ex eveniet", + "adjectiveAttributeValue": "facere molestiae aut", + "celebrateableId": "17", + "celebrateableType": "organization", + "changedAttributeName": "delectus aut nam", + "changedAttributeValue": "2011-04-05T20:54:44:94", + "commentsCount": 49810, + "id": "16", + "liked": true, + "likesCount": 7379, + "objectDescription": "fugit repellendus hic", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Anissa", + "id": "18", + "lastName": "Kirlin", + }, + "subjectPersonName": "Judge Doyle", }, + ], + "date": "2011-04-05T20:54:44:94", + "id": 8, + }, + Object { + "data": Array [ Object { - "adjective_attribute_value": "5", - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-01 12:00:00", - "id": "3", - "likes_count": 42, - "subject_person_name": "DG With me?", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quo occaecati quia", + "adjectiveAttributeValue": "ipsum sit qui", + "celebrateableId": "29", + "celebrateableType": "organizational_permission", + "changedAttributeName": "accusantium odit doloremque", + "changedAttributeValue": "2010-05-11T20:17:10:67", + "commentsCount": 50981, + "id": "28", + "liked": false, + "likesCount": 10213, + "objectDescription": "eos quis ut", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Dario", + "id": "30", + "lastName": "Lueilwitz", + }, + "subjectPersonName": "Orlando Schmidt", }, ], - "date": "2018-01-01 12:00:00", + "date": "2010-05-11T20:17:10:67", + "id": 9, }, ] } + stickyHeaderIndices={ + Array [ + 1, + 4, + 7, + 10, + ] + } stickySectionHeadersEnabled={true} style={ Object { @@ -197,77 +3266,581 @@ exports[`no header rendering renders correctly for no header 1`] = ` } updateCellsBatchingPeriod={50} windowSize={21} -/> -`; - -exports[`renderHeader match snapshot 1`] = ` - - // @ts-ignore - - - -`; - -exports[`renders section header 1`] = ` - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + /> + + `; -exports[`renders with clear notification set renders correctly with clear notification set 1`] = ` - + } refreshing={false} renderItem={[Function]} renderSectionHeader={[Function]} @@ -277,47 +3850,283 @@ exports[`renders with clear notification set renders correctly with clear notifi Object { "data": Array [ Object { - "adjective_attribute_value": "2", - "celebrateable_type": "accepted_challenge", - "changed_attribute_value": "2018-03-01 12:00:00", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sit vitae soluta", + "adjectiveAttributeValue": "sint non voluptates", + "celebrateableId": "5", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "ut ullam quos", + "changedAttributeValue": "2019-02-10T23:08:19:60", + "commentsCount": 58438, + "id": "4", + "liked": false, + "likesCount": 56591, + "objectDescription": "sunt laborum ratione", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Vern", + "id": "6", + "lastName": "McKenzie", + }, + "subjectPersonName": "Zola Corkery", + }, + ], + "date": "2019-02-10T23:08:19:60", + "id": 0, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quasi ipsum rem", + "adjectiveAttributeValue": "eos quod recusandae", + "celebrateableId": "26", + "celebrateableType": "story", + "changedAttributeName": "consectetur optio laudantium", + "changedAttributeValue": "2018-01-20T22:18:35:43", + "commentsCount": 6600, + "id": "25", + "liked": false, + "likesCount": 75546, + "objectDescription": "molestias facere quia", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Therese", + "id": "27", + "lastName": "Beatty", + }, + "subjectPersonName": "Hipolito Connelly", + }, + ], + "date": "2018-01-20T22:18:35:43", + "id": 1, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ullam minima ducimus", + "adjectiveAttributeValue": "temporibus modi aut", + "celebrateableId": "2", + "celebrateableType": "accepted_challenge", + "changedAttributeName": "architecto ducimus totam", + "changedAttributeValue": "2017-01-05T11:40:00:73", + "commentsCount": 90859, "id": "1", - "likes_count": 0, - "subject_person_name": "Roge Dog", + "liked": false, + "likesCount": 29361, + "objectDescription": "ut quis sed", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Breana", + "id": "3", + "lastName": "Ledner", + }, + "subjectPersonName": "Torey Abbott", }, + ], + "date": "2017-01-05T11:40:00:73", + "id": 2, + }, + Object { + "data": Array [ Object { - "adjective_attribute_value": "4", - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-03-01 12:00:00", - "id": "2", - "likes_count": 0, - "subject_person_name": "DG With me?", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quaerat cumque incidunt", + "adjectiveAttributeValue": "aut provident esse", + "celebrateableId": "8", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "hic eligendi quos", + "changedAttributeValue": "2016-07-31T16:52:49:08", + "commentsCount": 41417, + "id": "7", + "liked": true, + "likesCount": 4995, + "objectDescription": "voluptas sed quae", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Malcolm", + "id": "9", + "lastName": "Connelly", + }, + "subjectPersonName": "Grace Dibbert", }, ], - "date": "2018-03-01 12:00:00", + "date": "2016-07-31T16:52:49:08", + "id": 3, }, Object { "data": Array [ Object { - "adjective_attribute_value": "1", - "celebrateable_type": "accepted_challenge", - "changed_attribute_value": "2018-01-01 12:00:00", - "id": "4", - "likes_count": 11, - "subject_person_name": "Roge Dog", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "sint autem rerum", + "adjectiveAttributeValue": "doloremque officia aut", + "celebrateableId": "11", + "celebrateableType": "story", + "changedAttributeName": "ut ut eos", + "changedAttributeValue": "2014-08-26T07:39:14:97", + "commentsCount": 44798, + "id": "10", + "liked": false, + "likesCount": 89213, + "objectDescription": "consequatur vel in", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kaley", + "id": "12", + "lastName": "Cummerata", + }, + "subjectPersonName": "Marcellus Hyatt", + }, + ], + "date": "2014-08-26T07:39:14:97", + "id": 4, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "non aut rerum", + "adjectiveAttributeValue": "impedit ex rem", + "celebrateableId": "23", + "celebrateableType": "organization", + "changedAttributeName": "voluptates voluptas fuga", + "changedAttributeValue": "2014-06-14T18:46:15:61", + "commentsCount": 46739, + "id": "22", + "liked": false, + "likesCount": 26900, + "objectDescription": "non fugiat eligendi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Kathryne", + "id": "24", + "lastName": "Zieme", + }, + "subjectPersonName": "Tatyana Johns", + }, + ], + "date": "2014-06-14T18:46:15:61", + "id": 5, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "ex culpa earum", + "adjectiveAttributeValue": "voluptate vel labore", + "celebrateableId": "20", + "celebrateableType": "organization", + "changedAttributeName": "omnis ut est", + "changedAttributeValue": "2013-05-02T19:02:46:48", + "commentsCount": 57367, + "id": "19", + "liked": false, + "likesCount": 287, + "objectDescription": "est et sequi", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Ericka", + "id": "21", + "lastName": "Mayert", + }, + "subjectPersonName": "Daphney Balistreri", + }, + ], + "date": "2013-05-02T19:02:46:48", + "id": 6, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "et molestiae ea", + "adjectiveAttributeValue": "ut sunt placeat", + "celebrateableId": "14", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "quidem est consequuntur", + "changedAttributeValue": "2013-03-09T22:46:17:95", + "commentsCount": 88330, + "id": "13", + "liked": true, + "likesCount": 62367, + "objectDescription": "est placeat ex", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Favian", + "id": "15", + "lastName": "Ruecker", + }, + "subjectPersonName": "Roscoe Johnson", + }, + ], + "date": "2013-03-09T22:46:17:95", + "id": 7, + }, + Object { + "data": Array [ + Object { + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "enim ex eveniet", + "adjectiveAttributeValue": "facere molestiae aut", + "celebrateableId": "17", + "celebrateableType": "organization", + "changedAttributeName": "delectus aut nam", + "changedAttributeValue": "2011-04-05T20:54:44:94", + "commentsCount": 49810, + "id": "16", + "liked": true, + "likesCount": 7379, + "objectDescription": "fugit repellendus hic", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Anissa", + "id": "18", + "lastName": "Kirlin", + }, + "subjectPersonName": "Judge Doyle", }, + ], + "date": "2011-04-05T20:54:44:94", + "id": 8, + }, + Object { + "data": Array [ Object { - "adjective_attribute_value": "5", - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-01 12:00:00", - "id": "3", - "likes_count": 42, - "subject_person_name": "DG With me?", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "quo occaecati quia", + "adjectiveAttributeValue": "ipsum sit qui", + "celebrateableId": "29", + "celebrateableType": "organizational_permission", + "changedAttributeName": "accusantium odit doloremque", + "changedAttributeValue": "2010-05-11T20:17:10:67", + "commentsCount": 50981, + "id": "28", + "liked": false, + "likesCount": 10213, + "objectDescription": "eos quis ut", + "subjectPerson": Object { + "__typename": "Person", + "firstName": "Dario", + "id": "30", + "lastName": "Lueilwitz", + }, + "subjectPersonName": "Orlando Schmidt", }, ], - "date": "2018-01-01 12:00:00", + "date": "2010-05-11T20:17:10:67", + "id": 9, }, ] } + stickyHeaderIndices={ + Array [ + 1, + 4, + 7, + 10, + ] + } stickySectionHeadersEnabled={true} style={ Object { @@ -326,5 +4135,271 @@ exports[`renders with clear notification set renders correctly with clear notifi } updateCellsBatchingPeriod={50} windowSize={21} -/> +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; diff --git a/src/containers/CelebrateFeed/index.tsx b/src/containers/CelebrateFeed/index.tsx index 74399559dc..2bdfc149aa 100644 --- a/src/containers/CelebrateFeed/index.tsx +++ b/src/containers/CelebrateFeed/index.tsx @@ -29,7 +29,7 @@ import styles from './styles'; export const GET_CELEBRATE_FEED = gql` query GetCelebrateFeed( $communityId: ID! - $personId: ID + $personIds: [ID!] = null $hasUnreadComments: Boolean = false $celebrateCursor: String ) { @@ -38,7 +38,7 @@ export const GET_CELEBRATE_FEED = gql` sortBy: createdAt_ASC first: 25 after: $celebrateCursor - subjectPersonIds: [$personId] + subjectPersonIds: $personIds hasUnreadComments: $hasUnreadComments ) { nodes { @@ -110,7 +110,7 @@ const CelebrateFeed = ({ } = useQuery(GET_CELEBRATE_FEED, { variables: { communityId: organization.id, - personId: person.id, + personIds: (person && [person.id]) || undefined, hasUnreadComments: showUnreadOnly, }, pollInterval: 30000, @@ -130,7 +130,7 @@ const CelebrateFeed = ({ fetchMore({ variables: { communityId: organization.id, - personId: person.id, + personIds: (person && [person.id]) || undefined, hasUnreadComments: showUnreadOnly, celebrateCursor: endCursor, }, diff --git a/src/selectors/__tests__/__snapshots__/celebration.ts.snap b/src/selectors/__tests__/__snapshots__/celebration.ts.snap index 2f9a39af60..1d03922b0e 100644 --- a/src/selectors/__tests__/__snapshots__/celebration.ts.snap +++ b/src/selectors/__tests__/__snapshots__/celebration.ts.snap @@ -5,10 +5,20 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 2, - "celebrateable_type": "accepted_challenge", - "changed_attribute_value": "2018-01-07 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "accepted_challenge", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-07 00:00:00 UTC", + "commentsCount": 0, "id": "4", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-07 00:00:00 UTC", @@ -17,16 +27,36 @@ Array [ Object { "data": Array [ Object { - "celebrateable_type": "accepted_community_challenge", - "changed_attribute_name": "completed_at", - "changed_attribute_value": "2018-01-06 00:05:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "completed_at", + "changedAttributeValue": "2018-01-06 00:05:00 UTC", + "commentsCount": 0, "id": "9", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "celebrateable_type": "accepted_community_challenge", - "changed_attribute_name": "accepted_at", - "changed_attribute_value": "2018-01-06 00:04:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "accepted_at", + "changedAttributeValue": "2018-01-06 00:04:00 UTC", + "commentsCount": 0, "id": "8", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-06 00:05:00 UTC", @@ -35,10 +65,20 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 9, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-05 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "9", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-05 00:00:00 UTC", + "commentsCount": 0, "id": "5", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-05 00:00:00 UTC", @@ -47,22 +87,52 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 5, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-02 00:23:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "5", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-02 00:23:00 UTC", + "commentsCount": 0, "id": "6", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "adjective_attribute_value": 11, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-02 00:07:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "11", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-02 00:07:00 UTC", + "commentsCount": 0, "id": "3", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "adjective_attribute_value": 3, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-02 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "3", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-02 00:00:00 UTC", + "commentsCount": 0, "id": "7", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-02 00:23:00 UTC", @@ -71,10 +141,20 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 2, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-01 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-01 00:00:00 UTC", + "commentsCount": 0, "id": "1", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-01 00:00:00 UTC", @@ -83,10 +163,20 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 4, - "celebrateable_type": "interaction", - "changed_attribute_value": "2017-01-01 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "4", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2017-01-01 00:00:00 UTC", + "commentsCount": 0, "id": "2", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2017-01-01 00:00:00 UTC", @@ -95,22 +185,52 @@ Array [ Object { "data": Array [ Object { - "celebrateable_type": "organizational_permission", - "changed_attribute_name": "created_at", - "changed_attribute_value": "2016-12-25 00:09:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "organizational_permission", + "changedAttributeName": "created_at", + "changedAttributeValue": "2016-12-25 00:09:00 UTC", + "commentsCount": 0, "id": "11", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "celebrateable_type": "story", - "changed_attribute_name": "created_at", - "changed_attribute_value": "2016-12-25 00:09:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "story", + "changedAttributeName": "created_at", + "changedAttributeValue": "2016-12-25 00:09:00 UTC", + "commentsCount": 0, "id": "12", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "celebrateable_type": "organization", - "changed_attribute_name": "created_at", - "changed_attribute_value": "2016-12-25 00:02:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "organization", + "changedAttributeName": "created_at", + "changedAttributeValue": "2016-12-25 00:02:00 UTC", + "commentsCount": 0, "id": "10", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2016-12-25 00:09:00 UTC", @@ -124,10 +244,20 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 2, - "celebrateable_type": "accepted_challenge", - "changed_attribute_value": "2018-01-07 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "accepted_challenge", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-07 00:00:00 UTC", + "commentsCount": 0, "id": "4", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-07 00:00:00 UTC", @@ -136,16 +266,36 @@ Array [ Object { "data": Array [ Object { - "celebrateable_type": "accepted_community_challenge", - "changed_attribute_name": "completed_at", - "changed_attribute_value": "2018-01-06 00:05:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "completed_at", + "changedAttributeValue": "2018-01-06 00:05:00 UTC", + "commentsCount": 0, "id": "9", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "celebrateable_type": "accepted_community_challenge", - "changed_attribute_name": "accepted_at", - "changed_attribute_value": "2018-01-06 00:04:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "accepted_community_challenge", + "changedAttributeName": "accepted_at", + "changedAttributeValue": "2018-01-06 00:04:00 UTC", + "commentsCount": 0, "id": "8", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-06 00:05:00 UTC", @@ -154,10 +304,20 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 9, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-05 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "9", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-05 00:00:00 UTC", + "commentsCount": 0, "id": "5", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-05 00:00:00 UTC", @@ -166,22 +326,52 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 5, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-02 00:23:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "5", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-02 00:23:00 UTC", + "commentsCount": 0, "id": "6", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "adjective_attribute_value": 11, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-02 00:07:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "11", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-02 00:07:00 UTC", + "commentsCount": 0, "id": "3", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "adjective_attribute_value": 3, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-02 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "3", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-02 00:00:00 UTC", + "commentsCount": 0, "id": "7", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-02 00:23:00 UTC", @@ -190,10 +380,20 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 2, - "celebrateable_type": "interaction", - "changed_attribute_value": "2018-01-01 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2018-01-01 00:00:00 UTC", + "commentsCount": 0, "id": "1", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2018-01-01 00:00:00 UTC", @@ -202,10 +402,20 @@ Array [ Object { "data": Array [ Object { - "adjective_attribute_value": 4, - "celebrateable_type": "interaction", - "changed_attribute_value": "2017-01-01 00:00:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "4", + "celebrateableId": "1", + "celebrateableType": "interaction", + "changedAttributeName": "", + "changedAttributeValue": "2017-01-01 00:00:00 UTC", + "commentsCount": 0, "id": "2", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2017-01-01 00:00:00 UTC", @@ -214,22 +424,52 @@ Array [ Object { "data": Array [ Object { - "celebrateable_type": "organizational_permission", - "changed_attribute_name": "created_at", - "changed_attribute_value": "2016-12-25 00:09:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "organizational_permission", + "changedAttributeName": "created_at", + "changedAttributeValue": "2016-12-25 00:09:00 UTC", + "commentsCount": 0, "id": "11", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "celebrateable_type": "story", - "changed_attribute_name": "created_at", - "changed_attribute_value": "2016-12-25 00:09:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "story", + "changedAttributeName": "created_at", + "changedAttributeValue": "2016-12-25 00:09:00 UTC", + "commentsCount": 0, "id": "12", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, Object { - "celebrateable_type": "organization", - "changed_attribute_name": "created_at", - "changed_attribute_value": "2016-12-25 00:02:00 UTC", + "__typename": "CommunityCelebrationItem", + "adjectiveAttributeName": "", + "adjectiveAttributeValue": "2", + "celebrateableId": "1", + "celebrateableType": "organization", + "changedAttributeName": "created_at", + "changedAttributeValue": "2016-12-25 00:02:00 UTC", + "commentsCount": 0, "id": "10", + "liked": false, + "likesCount": 0, + "objectDescription": null, + "subjectPerson": null, + "subjectPersonName": null, }, ], "date": "2016-12-25 00:09:00 UTC", diff --git a/src/selectors/__tests__/celebration.ts b/src/selectors/__tests__/celebration.ts index 2dc7b0ea74..4056b88fc9 100644 --- a/src/selectors/__tests__/celebration.ts +++ b/src/selectors/__tests__/celebration.ts @@ -1,121 +1,129 @@ -import { celebrationSelector, celebrationItemSelector } from '../celebration'; +import { celebrationSelector } from '../celebration'; import { ACCEPTED_STEP } from '../../constants'; +import { GetCelebrateFeed_community_celebrationItems_nodes } from '../../containers/CelebrateFeed/__generated__/GetCelebrateFeed'; -const itemOne = { +const itemOne: GetCelebrateFeed_community_celebrationItems_nodes = { + __typename: 'CommunityCelebrationItem', id: '1', - celebrateable_type: 'interaction', - adjective_attribute_value: 2, - changed_attribute_value: '2018-01-01 00:00:00 UTC', + adjectiveAttributeName: '', + adjectiveAttributeValue: '2', + celebrateableId: '1', + celebrateableType: 'interaction', + changedAttributeName: '', + changedAttributeValue: '2018-01-01 00:00:00 UTC', + commentsCount: 0, + liked: false, + likesCount: 0, + objectDescription: null, + subjectPerson: null, + subjectPersonName: null, }; -const celebrateItems = [ +const celebrateItems: GetCelebrateFeed_community_celebrationItems_nodes[] = [ itemOne, { + ...itemOne, id: '2', - celebrateable_type: 'interaction', - adjective_attribute_value: 4, - changed_attribute_value: '2017-01-01 00:00:00 UTC', + celebrateableType: 'interaction', + adjectiveAttributeValue: '4', + changedAttributeValue: '2017-01-01 00:00:00 UTC', }, { + ...itemOne, id: '3', - celebrateable_type: 'interaction', - adjective_attribute_value: 11, - changed_attribute_value: '2018-01-02 00:07:00 UTC', + celebrateableType: 'interaction', + adjectiveAttributeValue: '11', + changedAttributeValue: '2018-01-02 00:07:00 UTC', }, { + ...itemOne, id: '4', - celebrateable_type: ACCEPTED_STEP, - adjective_attribute_value: 2, - changed_attribute_value: '2018-01-07 00:00:00 UTC', + celebrateableType: ACCEPTED_STEP, + adjectiveAttributeValue: '2', + changedAttributeValue: '2018-01-07 00:00:00 UTC', }, { + ...itemOne, id: '5', - celebrateable_type: 'interaction', - adjective_attribute_value: 9, - changed_attribute_value: '2018-01-05 00:00:00 UTC', + celebrateableType: 'interaction', + adjectiveAttributeValue: '9', + changedAttributeValue: '2018-01-05 00:00:00 UTC', }, { + ...itemOne, id: '6', - celebrateable_type: 'interaction', - adjective_attribute_value: 5, - changed_attribute_value: '2018-01-02 00:23:00 UTC', + celebrateableType: 'interaction', + adjectiveAttributeValue: '5', + changedAttributeValue: '2018-01-02 00:23:00 UTC', }, { + ...itemOne, id: '7', - celebrateable_type: 'interaction', - adjective_attribute_value: 3, - changed_attribute_value: '2018-01-02 00:00:00 UTC', + celebrateableType: 'interaction', + adjectiveAttributeValue: '3', + changedAttributeValue: '2018-01-02 00:00:00 UTC', }, { + ...itemOne, id: '8', - celebrateable_type: 'accepted_community_challenge', - changed_attribute_name: 'accepted_at', - changed_attribute_value: '2018-01-06 00:04:00 UTC', + celebrateableType: 'accepted_community_challenge', + changedAttributeName: 'accepted_at', + changedAttributeValue: '2018-01-06 00:04:00 UTC', }, { + ...itemOne, id: '9', - celebrateable_type: 'accepted_community_challenge', - changed_attribute_name: 'completed_at', - changed_attribute_value: '2018-01-06 00:05:00 UTC', + celebrateableType: 'accepted_community_challenge', + changedAttributeName: 'completed_at', + changedAttributeValue: '2018-01-06 00:05:00 UTC', }, { + ...itemOne, id: '10', - celebrateable_type: 'organization', - changed_attribute_name: 'created_at', - changed_attribute_value: '2016-12-25 00:02:00 UTC', + celebrateableType: 'organization', + changedAttributeName: 'created_at', + changedAttributeValue: '2016-12-25 00:02:00 UTC', }, { + ...itemOne, id: '11', - celebrateable_type: 'organizational_permission', - changed_attribute_name: 'created_at', - changed_attribute_value: '2016-12-25 00:09:00 UTC', + celebrateableType: 'organizational_permission', + changedAttributeName: 'created_at', + changedAttributeValue: '2016-12-25 00:09:00 UTC', }, { + ...itemOne, id: '12', - celebrateable_type: 'story', - changed_attribute_name: 'created_at', - changed_attribute_value: '2016-12-25 00:09:00 UTC', + celebrateableType: 'story', + changedAttributeName: 'created_at', + changedAttributeValue: '2016-12-25 00:09:00 UTC', }, ]; -const invalidItems = [ +const invalidItems: GetCelebrateFeed_community_celebrationItems_nodes[] = [ { + ...itemOne, id: '13', - celebrateable_type: 'interaction', - adjective_attribute_value: 42, - changed_attribute_value: '2018-01-01 00:00:00 UTC', + celebrateableType: 'interaction', + adjectiveAttributeValue: '42', + changedAttributeValue: '2018-01-01 00:00:00 UTC', }, { + ...itemOne, id: '14', - celebrateable_type: 'interaction', - adjective_attribute_value: 1, - changed_attribute_value: '2017-01-01 00:00:00 UTC', + celebrateableType: 'interaction', + adjectiveAttributeValue: '1', + changedAttributeValue: '2017-01-01 00:00:00 UTC', }, { + ...itemOne, id: '15', - celebrateable_type: 'roge', - adjective_attribute_value: 11, - changed_attribute_value: '2018-01-02 00:07:00 UTC', + celebrateableType: 'roge', + adjectiveAttributeValue: '11', + changedAttributeValue: '2018-01-02 00:07:00 UTC', }, ]; -describe('celebrationItemSelector', () => { - const org = { id: '314234234', celebrateItems: [itemOne] }; - - expect( - celebrationItemSelector( - { - organizations: { - all: [org], - surveysPagination: { page: 1, hasNextPage: false }, - membersPagination: { page: 1, hasNextPage: false }, - }, - }, - { organizationId: org.id, eventId: itemOne.id }, - ), - ).toEqual(itemOne); -}); - describe('celebrationSelector', () => { it('sorts items into sections by date', () => { expect(celebrationSelector({ celebrateItems })).toMatchSnapshot(); diff --git a/testUtils/globalMocks.ts b/testUtils/globalMocks.ts index 1199fc0334..4244315e91 100644 --- a/testUtils/globalMocks.ts +++ b/testUtils/globalMocks.ts @@ -1,5 +1,6 @@ import faker from 'faker/locale/en'; import { IMocks } from 'graphql-tools'; +import moment from 'moment'; let currentId = 1; const nextId = () => currentId++; @@ -9,12 +10,17 @@ export const resetGlobalMockSeeds = () => { }; resetGlobalMockSeeds(); +const ISO8601DateTime = () => faker.date.past(10, '2020-01-14').toUTCString(); + export const globalMocks: IMocks = { String: () => faker.lorem.words(), Int: () => faker.random.number(), Float: () => faker.random.number({ precision: 0.01 }), Boolean: () => faker.random.boolean(), ID: () => nextId(), + ISO8601DateTime, + ISO8601Date: () => + moment(faker.date.past(10, '2020-01-14')).format('YYYY-MM-DD'), BasePageInfo: () => ({ endCursor: null, @@ -37,4 +43,12 @@ export const globalMocks: IMocks = { Community: () => ({ name: faker.company.catchPhrase(), }), + CommunityCelebrateItem: () => { + const firstName = faker.name.firstName(); + const lastName = faker.name.lastName(); + return { + changedAttributeValue: ISO8601DateTime(), + subjectPersonName: `${firstName} ${lastName}`, + }; + }, }; From 7a3a9eb66b2595f7009004df97805b76cfd379ce Mon Sep 17 00:00:00 2001 From: Robert Eldredge Date: Wed, 29 Jan 2020 11:03:22 -0500 Subject: [PATCH 12/29] CelebrateItem tests --- .../CelebrateItem/__tests__/CelebrateItem.tsx | 89 +- .../__snapshots__/CelebrateItem.tsx.snap | 84 +- src/components/CelebrateItem/index.tsx | 2 +- .../__tests__/CelebrateItemContent.tsx | 184 ++-- .../CelebrateItemContent.tsx.snap | 95 --- src/components/CelebrateItemContent/index.tsx | 1 + .../__tests__/CelebrateItemName.tsx | 122 ++- .../__snapshots__/CelebrateItemName.tsx.snap | 116 ++- src/containers/CelebrateItemName/index.tsx | 8 +- .../__tests__/CommentLikeComponent.tsx | 301 ++++--- .../CommentLikeComponent.tsx.snap | 795 +++++++++++------- src/containers/CommentLikeComponent/index.tsx | 1 + testUtils/globalMocks.ts | 19 +- 13 files changed, 1079 insertions(+), 738 deletions(-) diff --git a/src/components/CelebrateItem/__tests__/CelebrateItem.tsx b/src/components/CelebrateItem/__tests__/CelebrateItem.tsx index ab3725d5bc..8b7c94798a 100644 --- a/src/components/CelebrateItem/__tests__/CelebrateItem.tsx +++ b/src/components/CelebrateItem/__tests__/CelebrateItem.tsx @@ -11,21 +11,27 @@ import { renderWithContext } from '../../../../testUtils'; import { CELEBRATEABLE_TYPES, GLOBAL_COMMUNITY_ID } from '../../../constants'; import { CELEBRATE_DETAIL_SCREEN } from '../../../containers/CelebrateDetailScreen'; import { CELEBRATE_EDIT_STORY_SCREEN } from '../../../containers/Groups/EditStoryScreen'; +import { Organization } from '../../../reducers/organizations'; +import { + GetCelebrateFeed_community_celebrationItems_nodes, + GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson, +} from '../../../containers/CelebrateFeed/__generated__/GetCelebrateFeed'; -import CelebrateItem, { Event, DELETE_STORY, REPORT_STORY } from '..'; +import CelebrateItem, { DELETE_STORY, REPORT_STORY } from '..'; jest.mock('../../../actions/analytics'); jest.mock('../../../actions/navigation'); const myId = '123'; -const subjectPerson = { +const subjectPerson: GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson = { + __typename: 'Person', id: '234', - first_name: 'John', - last_name: 'Smith', - full_name: 'John Smith', + firstName: 'John', + lastName: 'Smith', }; -const globalOrg = { id: GLOBAL_COMMUNITY_ID }; -const organization = { id: '3' }; +const subjectPersonName = `${subjectPerson.firstName} ${subjectPerson.lastName}`; +const globalOrg: Organization = { id: GLOBAL_COMMUNITY_ID }; +const organization: Organization = { id: '3' }; const date = '2019-08-21T12:00:00.000'; MockDate.set('2019-08-21 12:00:00', 300); @@ -36,19 +42,25 @@ let onClearNotification = jest.fn(); const trackActionResult = { type: 'tracked plain action' }; const navigatePushResult = { type: 'navigate push' }; -const event: Event = { +const baseEvent: GetCelebrateFeed_community_celebrationItems_nodes = { + __typename: 'CommunityCelebrationItem', id: '222', - changed_attribute_value: date, - subject_person: subjectPerson, - subject_person_name: subjectPerson.full_name, - celebrateable_id: '2', - celebrateable_type: CELEBRATEABLE_TYPES.completedStep, - organization, - object_description: 'Celebration', + adjectiveAttributeName: null, + adjectiveAttributeValue: null, + changedAttributeName: 'created_at', + changedAttributeValue: date, + commentsCount: 0, + liked: false, + likesCount: 1, + subjectPerson: subjectPerson, + subjectPersonName, + celebrateableId: '2', + celebrateableType: CELEBRATEABLE_TYPES.completedStep, + objectDescription: 'Celebration', }; -const storyEvent: Event = { - ...event, - celebrateable_type: CELEBRATEABLE_TYPES.story, +const storyEvent: GetCelebrateFeed_community_celebrationItems_nodes = { + ...baseEvent, + celebrateableType: CELEBRATEABLE_TYPES.story, }; const initialState = { auth: { person: { id: myId } } }; @@ -64,9 +76,10 @@ describe('global community', () => { it('renders correctly', () => { renderWithContext( , { initialState }, ).snapshot(); @@ -75,9 +88,10 @@ describe('global community', () => { it('renders with clear notification button correctly', () => { renderWithContext( , { initialState }, @@ -90,6 +104,7 @@ describe('global community', () => { event={storyEvent} onRefresh={onRefresh} organization={globalOrg} + namePressable={false} />, { initialState }, ).snapshot(); @@ -100,9 +115,10 @@ describe('Community', () => { it('renders correctly', () => { renderWithContext( , { initialState }, ).snapshot(); @@ -111,10 +127,11 @@ describe('Community', () => { it('renders with clear notification button correctly', () => { renderWithContext( , { initialState }, ).snapshot(); @@ -126,6 +143,7 @@ describe('Community', () => { event={storyEvent} onRefresh={onRefresh} organization={organization} + namePressable={false} />, { initialState }, ).snapshot(); @@ -135,7 +153,7 @@ describe('Community', () => { it('renders with name pressable correctly', () => { renderWithContext( { it('not pressable in global community', () => { const { getByTestId } = renderWithContext( , { initialState }, ); @@ -163,9 +182,10 @@ describe('press card', () => { it('navigates to celebrate detail screen', () => { const { getByTestId } = renderWithContext( , { initialState }, ); @@ -173,16 +193,17 @@ describe('press card', () => { fireEvent.press(getByTestId('CelebrateItemPressable')); expect(navigatePush).toHaveBeenCalledWith(CELEBRATE_DETAIL_SCREEN, { - event, + event: baseEvent, + orgId: organization.id, }); }); }); describe('long-press card', () => { describe('story written by me', () => { - const myStoryEvent = { + const myStoryEvent: GetCelebrateFeed_community_celebrationItems_nodes = { ...storyEvent, - subject_person: { ...subjectPerson, id: myId }, + subjectPerson: { ...subjectPerson, id: myId }, }; it('navigates to edit story screen', () => { @@ -194,6 +215,7 @@ describe('long-press card', () => { event={myStoryEvent} onRefresh={onRefresh} organization={organization} + namePressable={false} />, { initialState }, ); @@ -219,6 +241,7 @@ describe('long-press card', () => { event={myStoryEvent} onRefresh={onRefresh} organization={organization} + namePressable={false} />, { initialState }, ); @@ -242,7 +265,7 @@ describe('long-press card', () => { ], ); expect(useMutation).toHaveBeenMutatedWith(DELETE_STORY, { - variables: { input: { id: event.celebrateable_id } }, + variables: { input: { id: myStoryEvent.celebrateableId } }, }); expect(onRefresh).toHaveBeenCalled(); }); @@ -258,6 +281,7 @@ describe('long-press card', () => { event={storyEvent} onRefresh={onRefresh} organization={organization} + namePressable={false} />, { initialState }, ); @@ -281,7 +305,7 @@ describe('long-press card', () => { ], ); expect(useMutation).toHaveBeenMutatedWith(REPORT_STORY, { - variables: { subjectId: event.celebrateable_id }, + variables: { subjectId: storyEvent.celebrateableId }, }); }); }); @@ -291,16 +315,17 @@ describe('clear notification button', () => { it('calls onClearNotification', () => { const { getByTestId } = renderWithContext( , { initialState }, ); fireEvent.press(getByTestId('ClearNotificationButton')); - expect(onClearNotification).toHaveBeenCalledWith(event); + expect(onClearNotification).toHaveBeenCalledWith(baseEvent); }); }); diff --git a/src/components/CelebrateItem/__tests__/__snapshots__/CelebrateItem.tsx.snap b/src/components/CelebrateItem/__tests__/__snapshots__/CelebrateItem.tsx.snap index 50cc9d3d03..4f31d90292 100644 --- a/src/components/CelebrateItem/__tests__/__snapshots__/CelebrateItem.tsx.snap +++ b/src/components/CelebrateItem/__tests__/__snapshots__/CelebrateItem.tsx.snap @@ -111,7 +111,6 @@ exports[`Community renders correctly 1`] = ` Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -160,11 +159,14 @@ exports[`Community renders correctly 1`] = ` ] } > - // @ts-ignore - // @ts-ignore - // @ts-ignore - // @ts-ignore - // @ts-ignore - // @ts-ignore - // @ts-ignore { describe('CelebrateItemContent', () => { const testEvent = ( - e: Event, + e: GetCelebrateFeed_community_celebrationItems_nodes, otherProps: Partial = {}, ) => { - renderWithContext(, { - initialState, - }).snapshot(); + renderWithContext( + , + { + initialState, + }, + ).snapshot(); }; - it('renders event with fixed height', () => - testEvent(baseEvent, { fixedHeight: true })); - it('renders event with no subject person (global community event)', () => testEvent(baseEvent)); it('renders event with no subject person name', () => { - testEvent({ - ...baseEvent, - subject_person_name: null, - }); + testEvent( + { + ...baseEvent, + subjectPersonName: null, + }, + organization, + ); }); it('renders event for subject=me, liked=true, like count>0', () => { testEvent({ ...baseEvent, - subject_person: mePerson, - likes_count: 1, + subjectPerson: mePerson, + likesCount: 1, liked: true, }); }); @@ -79,8 +102,8 @@ describe('CelebrateItemContent', () => { it('renders event for subject=me, liked=false, like count>0', () => { testEvent({ ...baseEvent, - subject_person: mePerson, - likes_count: 1, + subjectPerson: mePerson, + likesCount: 1, liked: false, }); }); @@ -88,8 +111,8 @@ describe('CelebrateItemContent', () => { it('renders event for subject=me, liked=false, like count=0', () => { testEvent({ ...baseEvent, - subject_person: mePerson, - likes_count: 0, + subjectPerson: mePerson, + likesCount: 0, liked: false, }); }); @@ -97,8 +120,8 @@ describe('CelebrateItemContent', () => { it('renders event for subject=other, liked=true, like count>0', () => { testEvent({ ...baseEvent, - subject_person: otherPerson, - likes_count: 1, + subjectPerson: otherPerson, + likesCount: 1, liked: true, }); }); @@ -106,27 +129,27 @@ describe('CelebrateItemContent', () => { it('renders event for subject=other, liked=false, like count=0', () => { testEvent({ ...baseEvent, - subject_person: otherPerson, - likes_count: 0, + subjectPerson: otherPerson, + likesCount: 0, liked: false, }); }); describe('message', () => { - const messageBaseEvent = { + const messageBaseEvent: GetCelebrateFeed_community_celebrationItems_nodes = { ...baseEvent, - subject_person: mePerson, - likes_count: 0, + subjectPerson: mePerson, + likesCount: 0, liked: false, }; it('renders event with no subject person name', () => { testEvent({ ...messageBaseEvent, - subject_person: null, - subject_person_name: null, - celebrateable_type: CELEBRATEABLE_TYPES.completedStep, - adjective_attribute_value: '3', + subjectPerson: null, + subjectPersonName: null, + celebrateableType: CELEBRATEABLE_TYPES.completedStep, + adjectiveAttributeValue: '3', }); }); @@ -134,8 +157,8 @@ describe('CelebrateItemContent', () => { const testEventStage = (stageNum: string) => testEvent({ ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.completedStep, - adjective_attribute_value: stageNum, + celebrateableType: CELEBRATEABLE_TYPES.completedStep, + adjectiveAttributeValue: stageNum, }); it('1', () => testEventStage('1')); @@ -150,7 +173,7 @@ describe('CelebrateItemContent', () => { it('renders step of faith event without stage', () => { testEvent({ ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.completedStep, + celebrateableType: CELEBRATEABLE_TYPES.completedStep, }); }); @@ -158,8 +181,8 @@ describe('CelebrateItemContent', () => { const testEventInteraction = (interaction: string) => testEvent({ ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.completedInteraction, - adjective_attribute_value: interaction, + celebrateableType: CELEBRATEABLE_TYPES.completedInteraction, + adjectiveAttributeValue: interaction, }); it('personal decision', () => @@ -192,60 +215,40 @@ describe('CelebrateItemContent', () => { it('renders accepted challenge event', () => { testEvent({ ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.acceptedCommunityChallenge, - changed_attribute_name: CELEBRATEABLE_TYPES.challengeItemTypes.accepted, - object_description: 'Invite a friend to church', + celebrateableType: CELEBRATEABLE_TYPES.acceptedCommunityChallenge, + changedAttributeName: CELEBRATEABLE_TYPES.challengeItemTypes.accepted, + objectDescription: 'Invite a friend to church', }); }); it('renders completed challenge event', () => { testEvent({ ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.acceptedCommunityChallenge, - changed_attribute_name: - CELEBRATEABLE_TYPES.challengeItemTypes.completed, - object_description: 'Invite a friend to church', + celebrateableType: CELEBRATEABLE_TYPES.acceptedCommunityChallenge, + changedAttributeName: CELEBRATEABLE_TYPES.challengeItemTypes.completed, + objectDescription: 'Invite a friend to church', }); }); it('renders created community event', () => { testEvent({ ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.createdCommunity, - organization: { - name: 'Celebration Community', - }, + celebrateableType: CELEBRATEABLE_TYPES.createdCommunity, }); }); it('renders joined community event', () => { testEvent({ ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.joinedCommunity, - organization: { - name: 'Celebration Community', - }, + celebrateableType: CELEBRATEABLE_TYPES.joinedCommunity, }); }); - it('renders joined community with passed in org name', () => { - testEvent( - { - ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.joinedCommunity, - organization: { - name: 'Celebration Community', - }, - }, - { organization: { id: orgId, name: 'My Real Org' } }, - ); - }); - it('renders story', () => { testEvent({ ...messageBaseEvent, - celebrateable_type: CELEBRATEABLE_TYPES.story, - object_description: 'Once Upon a Time....', + celebrateableType: CELEBRATEABLE_TYPES.story, + objectDescription: 'Once Upon a Time....', }); }); }); @@ -255,31 +258,34 @@ describe('onPressChallengeLink', () => { it('navigates to challenge detail screen', () => { const challengeId = '123'; - const event = { + const event: GetCelebrateFeed_community_celebrationItems_nodes = { + ...baseEvent, id: '1', - subject_person_name: 'John Smith', - subject_person: { + subjectPersonName: 'John Smith', + subjectPerson: { + __typename: 'Person', id: otherId, + firstName: 'John', + lastName: 'Smith', }, - changed_attribute_value: '2004-04-04 00:00:00 UTC', - likes_count: 0, + changedAttributeValue: '2004-04-04 00:00:00 UTC', + likesCount: 0, liked: true, - organization: { id: orgId }, - celebrateable_type: CELEBRATEABLE_TYPES.acceptedCommunityChallenge, - changed_attribute_name: CELEBRATEABLE_TYPES.challengeItemTypes.completed, - adjective_attribute_value: challengeId, - object_description: 'Invite a friend to church', + celebrateableType: CELEBRATEABLE_TYPES.acceptedCommunityChallenge, + changedAttributeName: CELEBRATEABLE_TYPES.challengeItemTypes.completed, + adjectiveAttributeValue: challengeId, + objectDescription: 'Invite a friend to church', }; const { getByTestId, store } = renderWithContext( - , + , { initialState }, ); fireEvent.press(getByTestId('ChallengeLinkButton')); expect(navigatePush).toHaveBeenCalledWith(CHALLENGE_DETAIL_SCREEN, { challengeId, - orgId, + orgId: organization.id, }); expect(store.getActions()).toEqual([navigateResponse]); }); diff --git a/src/components/CelebrateItemContent/__tests__/__snapshots__/CelebrateItemContent.tsx.snap b/src/components/CelebrateItemContent/__tests__/__snapshots__/CelebrateItemContent.tsx.snap index dee45ca8ad..5a9d9bbcf4 100644 --- a/src/components/CelebrateItemContent/__tests__/__snapshots__/CelebrateItemContent.tsx.snap +++ b/src/components/CelebrateItemContent/__tests__/__snapshots__/CelebrateItemContent.tsx.snap @@ -7,7 +7,6 @@ exports[`CelebrateItemContent message renders accepted challenge event 1`] = ` Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -106,7 +105,6 @@ exports[`CelebrateItemContent message renders completed challenge event 1`] = ` Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -205,7 +203,6 @@ exports[`CelebrateItemContent message renders created community event 1`] = ` Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -239,7 +236,6 @@ exports[`CelebrateItemContent message renders event with no subject person name Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -273,7 +269,6 @@ exports[`CelebrateItemContent message renders interaction event discipleship 1`] Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -307,7 +302,6 @@ exports[`CelebrateItemContent message renders interaction event gospel 1`] = ` Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -341,7 +335,6 @@ exports[`CelebrateItemContent message renders interaction event holy spirit 1`] Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -375,7 +368,6 @@ exports[`CelebrateItemContent message renders interaction event not found 1`] = Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -409,7 +401,6 @@ exports[`CelebrateItemContent message renders interaction event personal decisio Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -443,7 +434,6 @@ exports[`CelebrateItemContent message renders interaction event something cool 1 Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -477,7 +467,6 @@ exports[`CelebrateItemContent message renders interaction event spiritual 1`] = Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -511,7 +500,6 @@ exports[`CelebrateItemContent message renders joined community event 1`] = ` Object { "marginTop": 14, }, - Object {}, undefined, ] } @@ -538,40 +526,6 @@ exports[`CelebrateItemContent message renders joined community event 1`] = ` `; -exports[`CelebrateItemContent message renders joined community with passed in org name 1`] = ` - - - John S. joined My Real Org! Now you can see and celebrate the steps of faith they are taking. - - -`; - exports[`CelebrateItemContent message renders step of faith event with stage 1 1`] = ` - - -`; - -exports[`CelebrateItemContent renders event with fixed height 1`] = ` - ); }; + export default connect()(CelebrateItemContent); diff --git a/src/containers/CelebrateItemName/__tests__/CelebrateItemName.tsx b/src/containers/CelebrateItemName/__tests__/CelebrateItemName.tsx index a44c5812dd..0132c358a7 100644 --- a/src/containers/CelebrateItemName/__tests__/CelebrateItemName.tsx +++ b/src/containers/CelebrateItemName/__tests__/CelebrateItemName.tsx @@ -1,90 +1,76 @@ import React from 'react'; -import configureStore from 'redux-mock-store'; +import { fireEvent } from 'react-native-testing-library'; import CelebrateItemName from '../index'; -import { renderShallow } from '../../../../testUtils'; +import { renderWithContext } from '../../../../testUtils'; import { navToPersonScreen } from '../../../actions/person'; - -const mockStore = configureStore(); -// @ts-ignore -let store; - -const navToPersonScreenResult = { type: 'navigated to person screen' }; -const person = { id: '1234123' }; -const organization = { id: '235234' }; - -// @ts-ignore -let name; -// @ts-ignore -let pressable; -// @ts-ignore -let screen; +import { Organization } from '../../../reducers/organizations'; +import { GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson } from '../../CelebrateFeed/__generated__/GetCelebrateFeed'; jest.mock('../../../actions/person'); -// @ts-ignore -navToPersonScreen.mockReturnValue(navToPersonScreenResult); +const person: GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson = { + __typename: 'Person', + id: '1234123', + firstName: 'Matt', + lastName: 'Smith', +}; +const name = `${person.firstName} ${person.lastName}`; +const organization: Organization = { + id: '235234', +}; + +const navToPersonScreenResult = { type: 'navigated to person screen' }; beforeEach(() => { - store = mockStore(); + (navToPersonScreen as jest.Mock).mockReturnValue(navToPersonScreenResult); +}); - screen = renderShallow( +it('renders correctly without name', () => { + renderWithContext( , - store, - ); + ).snapshot(); }); -describe('does not have name', () => { - beforeAll(() => { - name = null; - }); - - it('renders correctly', () => { - // @ts-ignore - expect(screen).toMatchSnapshot(); - }); +it('renders correctly with name', () => { + renderWithContext( + , + ).snapshot(); }); -describe('has name', () => { - beforeAll(() => { - name = 'Roger Goers'; - }); - - describe('is not pressable', () => { - beforeAll(() => { - pressable = false; - }); - - it('renders correctly', () => { - // @ts-ignore - expect(screen).toMatchSnapshot(); - }); - }); - - describe('is pressable', () => { - beforeAll(() => { - pressable = true; - }); +it('renders correctly not pressable', () => { + renderWithContext( + , + ).snapshot(); +}); - it('renders correctly', () => { - // @ts-ignore - expect(screen).toMatchSnapshot(); - }); +it('navigates to person screen', () => { + const { store, getByTestId } = renderWithContext( + , + ); - it('navigates to person screen', () => { - // @ts-ignore - screen.props().onPress(); + fireEvent.press(getByTestId('NameButton')); - expect(navToPersonScreen).toHaveBeenCalledWith(person, organization); - // @ts-ignore - expect(store.getActions()).toEqual([navToPersonScreenResult]); - }); - }); + expect(navToPersonScreen).toHaveBeenCalledWith(person, organization); + expect(store.getActions()).toEqual([navToPersonScreenResult]); }); diff --git a/src/containers/CelebrateItemName/__tests__/__snapshots__/CelebrateItemName.tsx.snap b/src/containers/CelebrateItemName/__tests__/__snapshots__/CelebrateItemName.tsx.snap index 69b7aab52b..9e9652eee3 100644 --- a/src/containers/CelebrateItemName/__tests__/__snapshots__/CelebrateItemName.tsx.snap +++ b/src/containers/CelebrateItemName/__tests__/__snapshots__/CelebrateItemName.tsx.snap @@ -1,24 +1,108 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`does not have name renders correctly 1`] = ` - +exports[`renders correctly not pressable 1`] = ` + + Matt Smith + `; -exports[`has name is not pressable renders correctly 1`] = ` - +exports[`renders correctly with name 1`] = ` + + + + Matt Smith + + + `; -exports[`has name is pressable renders correctly 1`] = ` - + MissionHub user + `; diff --git a/src/containers/CelebrateItemName/index.tsx b/src/containers/CelebrateItemName/index.tsx index 16640bf42f..131d07ccb9 100644 --- a/src/containers/CelebrateItemName/index.tsx +++ b/src/containers/CelebrateItemName/index.tsx @@ -9,11 +9,15 @@ import ItemHeaderText from '../../components/ItemHeaderText/index'; import { navToPersonScreen } from '../../actions/person'; import { GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson } from '../CelebrateFeed/__generated__/GetCelebrateFeed'; import { Organization } from '../../reducers/organizations'; +import { Person } from '../../reducers/people'; export interface CelebrateItemNameProps { dispatch: ThunkDispatch<{}, {}, AnyAction>; name: string | null; - person: GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson | null; + person: + | GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson + | Person + | null; organization: Organization; pressable: boolean; customContent?: JSX.Element; @@ -41,7 +45,7 @@ const CelebrateItemName = ({ } return ( - ); diff --git a/src/containers/CommentLikeComponent/__tests__/CommentLikeComponent.tsx b/src/containers/CommentLikeComponent/__tests__/CommentLikeComponent.tsx index 94123be32c..f8f9660feb 100644 --- a/src/containers/CommentLikeComponent/__tests__/CommentLikeComponent.tsx +++ b/src/containers/CommentLikeComponent/__tests__/CommentLikeComponent.tsx @@ -1,142 +1,253 @@ import 'react-native'; import React from 'react'; -import configureStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; +import { MockStore } from 'redux-mock-store'; +import { fireEvent, flushMicrotasksQueue } from 'react-native-testing-library'; +import { ReactTestInstance } from 'react-test-renderer'; -import { renderShallow, testSnapshotShallow } from '../../../../testUtils'; +import { renderWithContext } from '../../../../testUtils'; import { toggleLike } from '../../../actions/celebration'; import { ACTIONS } from '../../../constants'; import { trackActionWithoutData } from '../../../actions/analytics'; +import { Organization } from '../../../reducers/organizations'; +import { + GetCelebrateFeed_community_celebrationItems_nodes, + GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson, +} from '../../CelebrateFeed/__generated__/GetCelebrateFeed'; import CommentLikeComponent from '..'; jest.mock('../../../actions/celebration'); jest.mock('../../../actions/analytics'); -const mockStore = configureStore([thunk]); -// @ts-ignore -let store; - const myId = '2342'; +const otherId = '3453'; +const mePerson: GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson = { + __typename: 'Person', + id: myId, + firstName: 'Me', + lastName: 'Meme', +}; +const otherPerson: GetCelebrateFeed_community_celebrationItems_nodes_subjectPerson = { + __typename: 'Person', + id: otherId, + firstName: 'Other', + lastName: 'Otherother', +}; +const organization: Organization = { id: '567' }; +const baseEvent: GetCelebrateFeed_community_celebrationItems_nodes = { + __typename: 'CommunityCelebrationItem', + id: '777711', + adjectiveAttributeName: null, + adjectiveAttributeValue: null, + celebrateableId: '1', + celebrateableType: '', + changedAttributeName: '', + changedAttributeValue: '', + commentsCount: 15, + liked: false, + likesCount: 54, + objectDescription: null, + subjectPerson: null, + subjectPersonName: null, +}; + const toggleLikeResponse = { type: 'item was liked' }; const trackActionResponse = { type: 'tracked action' }; -// @ts-ignore -toggleLike.mockReturnValue(dispatch => dispatch(toggleLikeResponse)); -// @ts-ignore -trackActionWithoutData.mockReturnValue(dispatch => - dispatch(trackActionResponse), -); +const initialState = { auth: { person: { id: myId } } }; beforeEach(() => { - store = mockStore({ auth: { person: { id: myId } } }); + (toggleLike as jest.Mock).mockReturnValue(toggleLikeResponse); + (trackActionWithoutData as jest.Mock).mockReturnValue(trackActionResponse); }); it('renders nothing with no subject person', () => { - // @ts-ignore - testSnapshotShallow(, store); -}); - -it('renders with custom style', () => { - testSnapshotShallow( - // @ts-ignore - , - // @ts-ignore - store, - ); + renderWithContext( + , + { + initialState, + }, + ).snapshot(); }); -const event = { - id: '777711', - liked: false, - subject_person: {}, - likes_count: 54, - comments_count: 15, - organization: { id: '88732' }, -}; describe('with subject person', () => { it('renders for me', () => { - // @ts-ignore - testSnapshotShallow(, store); + renderWithContext( + , + { + initialState, + }, + ).snapshot(); }); it('renders for someone else', () => { - testSnapshotShallow( + renderWithContext( , - // @ts-ignore - store, - ); + { + initialState, + }, + ).snapshot(); }); it('renders when liked', () => { - testSnapshotShallow( - // @ts-ignore - , - // @ts-ignore - store, - ); + renderWithContext( + , + { + initialState, + }, + ).snapshot(); }); it('renders 0 comments_count', () => { - testSnapshotShallow( - // @ts-ignore - , - // @ts-ignore - store, - ); + renderWithContext( + , + { + initialState, + }, + ).snapshot(); }); it('renders 0 likes_count', () => { - testSnapshotShallow( - // @ts-ignore - , - // @ts-ignore - store, - ); - }); - - it('renders disabled heart button', () => { - const component = renderShallow( - // @ts-ignore - , - // @ts-ignore - store, - ); - component.setState({ isLikeDisabled: true }); - component.update(); - expect(component).toMatchSnapshot(); + renderWithContext( + , + { + initialState, + }, + ).snapshot(); }); describe('onPress like button', () => { - beforeEach(() => - // @ts-ignore - renderShallow(, store) - .childAt(3) - .props() - .onPress(), - ); - - it('toggles like', () => { - expect(toggleLike).toHaveBeenCalledWith( - event.id, - event.liked, - event.organization.id, - ); - // @ts-ignore - expect(store.getActions()).toEqual( - expect.arrayContaining([toggleLikeResponse]), - ); + describe('unlike -> like', () => { + let screen: { + store: MockStore; + recordSnapshot: () => void; + diffSnapshot: () => void; + getByTestId: (id: string) => ReactTestInstance; + }; + + beforeEach(() => { + screen = renderWithContext( + , + { + initialState, + }, + ); + }); + + it('renders disabled heart button', async () => { + screen.recordSnapshot(); + + fireEvent.press(screen.getByTestId('LikeIconButton')); + + screen.diffSnapshot(); + + await flushMicrotasksQueue(); + }); + + it('toggles like', async () => { + await fireEvent.press(screen.getByTestId('LikeIconButton')); + + expect(toggleLike).toHaveBeenCalledWith( + baseEvent.id, + false, + organization.id, + ); + expect(trackActionWithoutData).toHaveBeenCalledWith(ACTIONS.ITEM_LIKED); + expect(screen.store.getActions()).toEqual([ + toggleLikeResponse, + trackActionResponse, + ]); + }); }); - it('tracks action', () => { - expect(trackActionWithoutData).toHaveBeenCalledWith(ACTIONS.ITEM_LIKED); - // @ts-ignore - expect(store.getActions()).toEqual( - expect.arrayContaining([trackActionResponse]), - ); + describe('like -> unlike', () => { + let screen: { + store: MockStore; + recordSnapshot: () => void; + diffSnapshot: () => void; + getByTestId: (id: string) => ReactTestInstance; + }; + + beforeEach(() => { + screen = renderWithContext( + , + { + initialState, + }, + ); + }); + + it('renders disabled heart button', async () => { + screen.recordSnapshot(); + + fireEvent.press(screen.getByTestId('LikeIconButton')); + + screen.diffSnapshot(); + + await flushMicrotasksQueue(); + }); + + it('toggles like', async () => { + await fireEvent.press(screen.getByTestId('LikeIconButton')); + + expect(toggleLike).toHaveBeenCalledWith( + baseEvent.id, + true, + organization.id, + ); + expect(trackActionWithoutData).not.toHaveBeenCalled(); + expect(screen.store.getActions()).toEqual([toggleLikeResponse]); + }); }); }); }); diff --git a/src/containers/CommentLikeComponent/__tests__/__snapshots__/CommentLikeComponent.tsx.snap b/src/containers/CommentLikeComponent/__tests__/__snapshots__/CommentLikeComponent.tsx.snap index ac18af6223..accedc1a58 100644 --- a/src/containers/CommentLikeComponent/__tests__/__snapshots__/CommentLikeComponent.tsx.snap +++ b/src/containers/CommentLikeComponent/__tests__/__snapshots__/CommentLikeComponent.tsx.snap @@ -2,100 +2,151 @@ exports[`renders nothing with no subject person 1`] = ` - - + /> + + `; -exports[`renders with custom style 1`] = ` - - - - +exports[`with subject person onPress like button like -> unlike renders disabled heart button 1`] = ` +"Snapshot Diff: +- First value ++ Second value + +@@ -80,11 +80,13 @@ + style={ + Array [ + Object { + \\"backgroundColor\\": \\"transparent\\", + }, +- null, ++ Object { ++ \\"opacity\\": 0.6, ++ }, + Object { + \\"height\\": 24, + \\"width\\": 24, + }, + null," +`; + +exports[`with subject person onPress like button unlike -> like renders disabled heart button 1`] = ` +"Snapshot Diff: +- First value ++ Second value + +@@ -80,11 +80,13 @@ + style={ + Array [ + Object { + \\"backgroundColor\\": \\"transparent\\", + }, +- null, ++ Object { ++ \\"opacity\\": 0.6, ++ }, + Object { + \\"height\\": 24, + \\"width\\": 24, + }, + null," `; exports[`with subject person renders 0 comments_count 1`] = ` - - - + /> + + `; exports[`with subject person renders 0 likes_count 1`] = ` - - 15 - - - - - -`; - -exports[`with subject person renders disabled heart button 1`] = ` - - 15 - + - - + /> + + `; exports[`with subject person renders for me 1`] = ` - 15 - + - - + /> + + `; exports[`with subject person renders for someone else 1`] = ` - 15 - + - - 54 - - + /> + + `; exports[`with subject person renders when liked 1`] = ` - 15 - + - - + /> + + `; diff --git a/src/containers/CommentLikeComponent/index.tsx b/src/containers/CommentLikeComponent/index.tsx index 5fe4dd618b..caaddc715e 100644 --- a/src/containers/CommentLikeComponent/index.tsx +++ b/src/containers/CommentLikeComponent/index.tsx @@ -67,6 +67,7 @@ const CommentLikeComponent = ({ {displayLikeCount ? likesCount : null}