Skip to content

Commit

Permalink
Merge pull request #344 from steniowagner/feat/search
Browse files Browse the repository at this point in the history
Feat/search
  • Loading branch information
steniowagner authored Nov 6, 2023
2 parents eb66b38 + b43c008 commit 9a0ec8f
Show file tree
Hide file tree
Showing 55 changed files with 3,022 additions and 129 deletions.
1 change: 1 addition & 0 deletions __mocks__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { MockedNavigator } from './MockedNavigator';
export * from './news';
export * from './quiz-questions';
export * from './trending-famous';
export * from './search';
193 changes: 193 additions & 0 deletions __mocks__/search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import { DocumentNode, GraphQLError } from 'graphql';

import { SEARCH_FAMOUS_QUERY } from '@/components/stacks/common-screens/search/search-config/search-famous-config';
import { SEARCH_MOVIES_QUERY } from '@/components/stacks/common-screens/search/search-config/search-movies-config';
import { SEARCH_TV_SHOWS_QUERY } from '@/components/stacks/common-screens/search/search-config/search-tv-shows-config';
import { DEFAULT_HEIGHT } from '@/components/common/default-tmdb-list-item/DefaultTMDBListItem.styles';
import {
SearchType,
SearchItem,
} from '@/components/stacks/common-screens/search/types';
import metrics from '@/styles/metrics';
import { ISO6391Language } from '@/types/schema';
import { getErrorType } from './utils';

type BaseMockSearchQueryResponseParams = {
items: SearchItem[];
type: SearchType;
page: number;
hasMore: boolean;
query: string;
};

export const SEARCH_ITEMS_PER_PAGE = Math.floor(
metrics.height / DEFAULT_HEIGHT,
);

export const searchItemsList = (page = 1) =>
Array(SEARCH_ITEMS_PER_PAGE)
.fill({})
.map((_, index) => ({
image: `page${page}-image-${index}`,
title: `page${page}-title-${index}-${page}`,
id: page * SEARCH_ITEMS_PER_PAGE + index,
})) as SearchItem[];

const baseMockSearchQueryResponse = (
params: BaseMockSearchQueryResponseParams,
) => {
const searchTypeQueryMapping: Record<SearchType, DocumentNode> = {
[SearchType.FAMOUS]: SEARCH_FAMOUS_QUERY,
[SearchType.MOVIE]: SEARCH_MOVIES_QUERY,
[SearchType.TV]: SEARCH_TV_SHOWS_QUERY,
};
const request = {
request: {
query: searchTypeQueryMapping[params.type],
variables: {
input: {
language: ISO6391Language.en,
page: params.page,
query: params.query,
},
},
},
};
const result = {
result: {
data: {
search: {
hasMore: params.hasMore,
items: params.items,
},
},
},
};

const responseWithNetworkError = {
...request,
error: new Error('A Network error occurred'),
};

const responseWithGraphQLError = {
...request,
errors: [new GraphQLError('A GraphQL error occurred')],
};

return {
responseWithGraphQLError,
responseWithNetworkError,
request,
result,
};
};

type MockSearchEntryQuerySuccessResponseParams = {
hasMore: boolean;
type: SearchType;
query: string;
};

export const mockSearchEntryQuerySuccessResponse = (
params: MockSearchEntryQuerySuccessResponseParams,
) => {
const entryQueryResult = baseMockSearchQueryResponse({
items: searchItemsList(),
page: 1,
query: params.query,
type: params.type,
hasMore: params.hasMore,
});
return [
{
...entryQueryResult.request,
...entryQueryResult.result,
},
];
};

export const mockSearchEntryQueryErrorResponse = (
params: MockSearchEntryQuerySuccessResponseParams,
) => {
const error = getErrorType();
const entryQueryResult = baseMockSearchQueryResponse({
items: [],
page: 1,
query: params.query,
type: params.type,
hasMore: false,
});
const errorResponse =
error === 'network'
? entryQueryResult.responseWithNetworkError
: entryQueryResult.responseWithGraphQLError;
return [
{
...entryQueryResult.request,
...errorResponse,
},
];
};

export const mockSearchPaginationQuerySuccessResponse = (
params: MockSearchEntryQuerySuccessResponseParams,
) => {
const entryQueryResult = baseMockSearchQueryResponse({
items: searchItemsList(),
page: 1,
query: params.query,
type: params.type,
hasMore: params.hasMore,
});
const paginationQueryResult = baseMockSearchQueryResponse({
items: searchItemsList(2),
page: 2,
query: params.query,
type: params.type,
hasMore: params.hasMore,
});
return [
{
...entryQueryResult.request,
...entryQueryResult.result,
},
{
...paginationQueryResult.request,
...paginationQueryResult.result,
},
];
};

export const mockSearchPaginationQueryErrorResponse = (
params: MockSearchEntryQuerySuccessResponseParams,
) => {
const error = getErrorType();
const entryQueryResult = baseMockSearchQueryResponse({
items: searchItemsList(),
page: 1,
query: params.query,
type: params.type,
hasMore: params.hasMore,
});
const paginationQueryResult = baseMockSearchQueryResponse({
items: [],
page: 2,
query: params.query,
type: params.type,
hasMore: false,
});
const errorResponse =
error === 'network'
? paginationQueryResult.responseWithNetworkError
: paginationQueryResult.responseWithGraphQLError;
return [
{
...entryQueryResult.request,
...entryQueryResult.result,
},
{
...paginationQueryResult.request,
...errorResponse,
},
];
};
2 changes: 1 addition & 1 deletion __mocks__/trending-famous.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GraphQLError } from 'graphql';

import { QUERY_TRENDING_FAMOUS } from '@/components/stacks/famous/screens/trending-famous/use-trending-famous';
import { DEFAULT_HEIGHT } from '@/components/stacks/famous/screens/trending-famous/components/trending-famous-list-item/TrendingFamousListItem.styles';
import { DEFAULT_HEIGHT } from '@/components/common/default-tmdb-list-item/DefaultTMDBListItem.styles';
import { QueryTrendingFamous_trendingFamous_items } from '@/types/schema';
import metrics from '@styles/metrics';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { StyleSheet } from 'react-native';
import styled from 'styled-components/native';

import { Typography } from '@/components/common';
import { borderRadius } from '@/styles/border-radius';
import metrics from '@styles/metrics';

export const DEFAULT_ICON_SIZE = metrics.xl * 3;
export const DEFAULT_WIDTH = metrics.getWidthFromDP('30');
export const DEFAULT_HEIGHT = metrics.getWidthFromDP('50');
export const DEFAULT_BORDER_RADIUS = metrics.xs;
export const DEFAULT_MARGIN_BOTTOM = metrics.xl;
export const DEFAULT_MARGIN_LEFT = metrics.getWidthFromDP('2.5');
const IMAGE_WIDTH = metrics.getWidthFromDP('30');
const IMAGE_HEIGHT = metrics.getWidthFromDP('40');
const TEXT_MARGIN_TOP = metrics.sm;

export const FamousName = styled(Typography.ExtraSmallText).attrs({
numberOfLines: 2,
bold: true,
})`
margin-top: ${TEXT_MARGIN_TOP}px;
`;

export const Wrapper = styled.TouchableOpacity`
width: ${DEFAULT_WIDTH}px;
height: ${DEFAULT_HEIGHT}px;
margin-bottom: ${DEFAULT_MARGIN_BOTTOM}px;
margin-left: ${DEFAULT_MARGIN_LEFT}px;
`;

export const sheet = StyleSheet.create({
image: {
width: IMAGE_WIDTH,
height: IMAGE_HEIGHT,
borderRadius: DEFAULT_BORDER_RADIUS,
},
loading: {
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
},
loadingImage: {
width: IMAGE_WIDTH,
height: IMAGE_HEIGHT,
borderRadius: DEFAULT_BORDER_RADIUS,
},
loadingText: {
width: IMAGE_WIDTH,
height: metrics.lg,
borderRadius: borderRadius.xs,
marginTop: TEXT_MARGIN_TOP,
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React, { memo } from 'react';

import { Icons, TMDBImage } from '@common-components';

import * as Styles from './DefaultTMDBListItem.styles';

type DefaultTMDBListItemProps = {
iconImageLoading: Icons;
iconImageError: Icons;
onPress: () => void;
testID: string;
image: string;
title: string;
};

export const DefaultTMDBListItem = memo(
(props: DefaultTMDBListItemProps) => (
<Styles.Wrapper testID={props.testID} onPress={props.onPress}>
<TMDBImage
imageType="profile"
image={props.image}
style={Styles.sheet.image}
iconImageLoading={props.iconImageLoading}
iconImageError={props.iconImageError}
iconSize={Styles.DEFAULT_ICON_SIZE}
/>
<Styles.FamousName testID="title-text">{props.title}</Styles.FamousName>
</Styles.Wrapper>
),
() => true,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styled from 'styled-components/native';

import {
DEFAULT_MARGIN_LEFT,
DEFAULT_HEIGHT,
} from '../default-tmdb-list-item/DefaultTMDBListItem.styles';
import metrics from '@/styles/metrics';

const NUMBER_OF_COLUMNS = 3;
export const NUMBER_OF_LOADING_ITEMS = Math.ceil(
NUMBER_OF_COLUMNS * (metrics.height / DEFAULT_HEIGHT) + 1,
);

export const LoadingWrapper = styled.View`
flex: 1;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
padding-top: ${({ theme }) => theme.metrics.md}px;
padding-horizontal: ${DEFAULT_MARGIN_LEFT}px;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { View } from 'react-native';

import * as DefaultTMDBListItemStyles from '../default-tmdb-list-item/DefaultTMDBListItem.styles';
import * as Styles from './DefaultTMDBListLoading.styles';
import { LoadingPlaceholder } from '..';

export const DefaultTMDBListLoading = () => (
<Styles.LoadingWrapper testID="default-tmdb-list-loading">
{Array(Styles.NUMBER_OF_LOADING_ITEMS)
.fill({})
.map((_, index) => (
<View style={DefaultTMDBListItemStyles.sheet.loading} key={index}>
<LoadingPlaceholder
style={DefaultTMDBListItemStyles.sheet.loadingImage}
indexToDelayAnimation={index}
/>
<LoadingPlaceholder
style={DefaultTMDBListItemStyles.sheet.loadingText}
indexToDelayAnimation={index}
/>
</View>
))}
</Styles.LoadingWrapper>
);
2 changes: 2 additions & 0 deletions src/components/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ export { PaginatedListHeader } from './paginated-list-header/PaginatedListHeader
export { Advice } from './advice/Advice';
export { RoundedButton } from './rounded-button/RoundedButton';
export { TMDBImage } from './tmdb-image/TMDBImage';
export { DefaultTMDBListItem } from './default-tmdb-list-item/DefaultTMDBListItem';
export { DefaultTMDBListLoading } from './default-tmdb-list-loading/DefaultTMDBListLoading';
1 change: 1 addition & 0 deletions src/components/stacks/common-screens/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Search } from './search/Search';
Loading

0 comments on commit 9a0ec8f

Please sign in to comment.