Skip to content

Commit

Permalink
[react] Fetch reactions to story for content card (#87)
Browse files Browse the repository at this point in the history
* accidently forgot to branch

* mergong

* reactions added to the PreviewCard and ContentCard

* prettier problems

* minor change

* fixed small error

* Improve performence

* Preload reactions

* Clean up code

* Make content card use string[]

* Add null checks for preview length

* Add reactions display component

* Run prettier

---------

Co-authored-by: Marcos Hernandez <[email protected]>
Co-authored-by: Aditya Pawar <[email protected]>
Co-authored-by: Aditya Pawar <[email protected]>
  • Loading branch information
4 people committed Apr 21, 2024
1 parent e0ffb52 commit 70b0844
Show file tree
Hide file tree
Showing 17 changed files with 202 additions and 71 deletions.
4 changes: 2 additions & 2 deletions src/app/(tabs)/author/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as cheerio from 'cheerio';
import { useLocalSearchParams, router } from 'expo-router';
import { decode } from 'html-entities';
import { useEffect, useState } from 'react';
import { ActivityIndicator, ScrollView, View, Text, Image } from 'react-native';
import { ActivityIndicator, ScrollView, View, Text } from 'react-native';
import { Image } from 'expo-image';
import { SafeAreaView } from 'react-native-safe-area-context';

import styles from './styles';
Expand Down
2 changes: 2 additions & 0 deletions src/app/(tabs)/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ function HomeScreen() {
>
{recommendedStories.map(story => (
<ContentCard
id={story.id}
key={story.title}
title={story.title}
author={story.author_name}
Expand Down Expand Up @@ -159,6 +160,7 @@ function HomeScreen() {
>
{newStories.map(story => (
<ContentCard
id={story.id}
key={story.title}
title={story.title}
author={story.author_name}
Expand Down
22 changes: 15 additions & 7 deletions src/app/(tabs)/search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ import PreviewCard from '../../../components/PreviewCard/PreviewCard';
import RecentSearchCard from '../../../components/RecentSearchCard/RecentSearchCard';
import { fetchGenres } from '../../../queries/genres';
import { fetchAllStoryPreviews } from '../../../queries/stories';
import { StoryPreview, RecentSearch, Genre } from '../../../queries/types';
import {
StoryPreview,
RecentSearch,
Genre,
StoryPreviewWithPreloadedReactions,
} from '../../../queries/types';
import colors from '../../../styles/colors';
import globalStyles from '../../../styles/globalStyles';
import { GenreType } from '../genre';
Expand Down Expand Up @@ -62,9 +67,13 @@ const setRecentStory = async (recentStories: StoryPreview[]) => {
};

function SearchScreen() {
const [allStories, setAllStories] = useState<StoryPreview[]>([]);
const [allStories, setAllStories] = useState<
StoryPreviewWithPreloadedReactions[]
>([]);
const [allGenres, setAllGenres] = useState<Genre[]>([]);
const [searchResults, setSearchResults] = useState<StoryPreview[]>([]);
const [searchResults, setSearchResults] = useState<
StoryPreviewWithPreloadedReactions[]
>([]);
const [search, setSearch] = useState('');
const [filterVisible, setFilterVisible] = useState(false);
const [recentSearches, setRecentSearches] = useState<RecentSearch[]>([]);
Expand All @@ -75,9 +84,7 @@ function SearchScreen() {

useEffect(() => {
(async () => {
fetchAllStoryPreviews().then((stories: StoryPreview[]) =>
setAllStories(stories),
);
fetchAllStoryPreviews().then(stories => setAllStories(stories));
fetchGenres().then((genres: Genre[]) => setAllGenres(genres));
getRecentSearch().then((searches: RecentSearch[]) =>
setRecentSearches(searches),
Expand All @@ -99,7 +106,7 @@ function SearchScreen() {
return;
}

const updatedData = allStories.filter((item: StoryPreview) => {
const updatedData = allStories.filter(item => {
const title = `${item.title.toUpperCase()})`;
const author = `${item.author_name.toUpperCase()})`;
const text_data = text.toUpperCase();
Expand Down Expand Up @@ -400,6 +407,7 @@ function SearchScreen() {
storyId={item.id}
title={item.title}
image={item.featured_media}
reactions={item.reactions}
author={item.author_name}
authorImage={item.author_image}
excerpt={item.excerpt}
Expand Down
2 changes: 1 addition & 1 deletion src/app/(tabs)/story/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import React, { useEffect, useState } from 'react';
import {
ActivityIndicator,
FlatList,
Image,
ScrollView,
Share,
Text,
TouchableOpacity,
View,
useWindowDimensions,
} from 'react-native';
import { Image } from 'expo-image';
import { Button } from 'react-native-paper';
import { RenderHTML } from 'react-native-render-html';
import { SafeAreaView } from 'react-native-safe-area-context';
Expand Down
5 changes: 2 additions & 3 deletions src/app/auth/verify/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Link, Redirect, router, useLocalSearchParams } from 'expo-router';
import { Redirect, router, useLocalSearchParams } from 'expo-router';
import { useState, useRef, useEffect } from 'react';
import { View, Text } from 'react-native';
import { Icon } from 'react-native-elements';
import OTPTextInput from 'react-native-otp-textinput';
import { SafeAreaView } from 'react-native-safe-area-context';
import Toast, { BaseToast, BaseToastProps } from 'react-native-toast-message';
import Toast from 'react-native-toast-message';

import styles from './styles';
import BackButton from '../../../components/BackButton/BackButton';
Expand Down
3 changes: 2 additions & 1 deletion src/components/AuthorCard/AuthorCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Image, Text, View } from 'react-native';
import { Image } from 'expo-image';
import { Text, View } from 'react-native';
import styles from './styles';

type AuthorCardProps = {
Expand Down
42 changes: 23 additions & 19 deletions src/components/ContentCard/ContentCard.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { Image } from 'expo-image';
import { useEffect, useState } from 'react';
import {
GestureResponderEvent,
Pressable,
Text,
View,
TouchableOpacity,
} from 'react-native';
import { Image } from 'expo-image';
import Emoji from 'react-native-emoji';

import styles from './styles';
import { fetchAllReactionsToStory } from '../../queries/reactions';
import { Reactions } from '../../queries/types';
import globalStyles from '../../styles/globalStyles';
import Emoji from 'react-native-emoji';
import SaveStoryButton from '../SaveStoryButton/SaveStoryButton';
import ReactionDisplay from '../ReactionDisplay/ReactionDisplay';

type ContentCardProps = {
id: number;
title: string;
author: string;
image: string;
Expand All @@ -22,13 +27,28 @@ type ContentCardProps = {
};

function ContentCard({
id,
title,
author,
image,
authorImage,
storyId,
pressFunction,
}: ContentCardProps) {
const [reactions, setReactions] = useState<string[]>();

useEffect(() => {
(async () => {
const temp = await fetchAllReactionsToStory(id);
if (temp != null) {
setReactions(temp.map(r => r.reaction));
return;
}

setReactions([]);
})();
}, []);

return (
<Pressable onPress={pressFunction}>
<View style={styles.contentCard}>
Expand Down Expand Up @@ -58,23 +78,7 @@ function ContentCard({
</Text>
</View>
<View style={styles.buttons}>
<View style={{ flexDirection: 'row', gap: -7 }}>
<View style={[styles.reactions, { backgroundColor: '#FFCCCB' }]}>
<Emoji name="heart" />
</View>
<View style={[styles.reactions, { backgroundColor: '#FFD580' }]}>
<Emoji name="clap" />
</View>
<View style={[styles.reactions, { backgroundColor: '#89CFF0' }]}>
<Emoji name="muscle" />
</View>
{/* heart, clap, muscle, cry, ??? */}
<View style={styles.reactionNumber}>
<Text style={[globalStyles.subtext, styles.reactionText]}>
14{/*change number to work*/}
</Text>
</View>
</View>
<ReactionDisplay reactions={reactions ?? []} />
<TouchableOpacity>
<SaveStoryButton storyId={storyId} />
</TouchableOpacity>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
GestureResponderEvent,
Text,
Image,
View,
TouchableOpacity,
} from 'react-native';
import { Image } from 'expo-image';

import styles from './styles';
import globalStyles from '../../styles/globalStyles';
Expand Down
46 changes: 25 additions & 21 deletions src/components/PreviewCard/PreviewCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import * as cheerio from 'cheerio';
import { Image } from 'expo-image';
import { useEffect, useState } from 'react';
import {
GestureResponderEvent,
Pressable,
Expand All @@ -7,11 +9,13 @@ import {
View,
} from 'react-native';
import Emoji from 'react-native-emoji';
import { Image } from 'expo-image';

import styles from './styles';
import { fetchAllReactionsToStory } from '../../queries/reactions';
import { Reactions } from '../../queries/types';
import globalStyles from '../../styles/globalStyles';
import SaveStoryButton from '../SaveStoryButton/SaveStoryButton';
import ReactionDisplay from '../ReactionDisplay/ReactionDisplay';

const placeholderImage =
'https://gwn-uploads.s3.amazonaws.com/wp-content/uploads/2021/10/10120952/Girls-Write-Now-logo-avatar.png';
Expand All @@ -24,6 +28,7 @@ type PreviewCardProps = {
authorImage: string;
excerpt: { html: string };
tags: string[];
reactions?: string[] | null;
pressFunction: (event: GestureResponderEvent) => void;
};

Expand All @@ -36,10 +41,25 @@ function PreviewCard({
excerpt,
tags,
pressFunction,
reactions: preloadedReactions = null,
}: PreviewCardProps) {
const saveStory = () => {
console.log("testing '+' icon does something for story " + title);
};
const [reactions, setReactions] = useState<string[] | null>(
preloadedReactions,
);
useEffect(() => {
if (preloadedReactions != null) {
return;
}

(async () => {
const temp = await fetchAllReactionsToStory(storyId);
if (temp != null) {
setReactions(temp.map(r => r.reaction));
return;
}
setReactions([]);
})();
}, []);

return (
<Pressable onPress={pressFunction}>
Expand Down Expand Up @@ -76,23 +96,7 @@ function PreviewCard({
</View>
</View>
<View style={styles.tagsContainer}>
<View style={{ flexDirection: 'row', gap: -7 }}>
<View style={[styles.reactions, { backgroundColor: '#FFCCCB' }]}>
<Emoji name="heart" />
</View>
<View style={[styles.reactions, { backgroundColor: '#FFD580' }]}>
<Emoji name="clap" />
</View>
<View style={[styles.reactions, { backgroundColor: '#89CFF0' }]}>
<Emoji name="muscle" />
</View>
{/* heart, clap, muscle, cry, ??? */}
<View style={styles.reactionNumber}>
<Text style={[globalStyles.subtext, styles.reactionText]}>
14{/*change number to work*/}
</Text>
</View>
</View>
<ReactionDisplay reactions={reactions ?? []} />
<View style={styles.tagsRow}>
{(tags?.length ?? 0) > 0 && (
<View style={styles.tag}>
Expand Down
60 changes: 60 additions & 0 deletions src/components/ReactionDisplay/ReactionDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Text, View } from 'react-native';
import styles from './styles';
import Emoji from 'react-native-emoji';
import globalStyles from '../../styles/globalStyles';

type ReactionDisplayProps = {
reactions: string[];
};

function ReactionDisplay({ reactions }: ReactionDisplayProps) {
const reactionColors: Record<string, string> = {
heart: '#FFCCCB',
clap: '#FFD580',
cry: '#89CFF0',
hugging_face: '#ffc3bf',
muscle: '#eddcf7',
};
const defaultColor = reactionColors['heart'];
const setOfReactions = [...reactions];
setOfReactions.push('heart');
setOfReactions.push('clap');
setOfReactions.push('muscle');

const reactionDisplay = [...new Set(setOfReactions)].slice(0, 3);

return (
<View
style={{
flexDirection: 'row',
gap: -7,
}}
>
{reactionDisplay.map(reaction => {
return (
<View
key={reaction}
style={[
styles.reactions,
{
backgroundColor:
reaction in reactionColors
? reactionColors[reaction]
: defaultColor,
},
]}
>
<Emoji name={reaction} />
</View>
);
})}
<View style={styles.reactionNumber}>
<Text style={[globalStyles.subtext, styles.reactionText]}>
{reactions?.length ?? 0}
</Text>
</View>
</View>
);
}

export default ReactionDisplay;
27 changes: 27 additions & 0 deletions src/components/ReactionDisplay/styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { StyleSheet } from 'react-native';
import colors from '../../styles/colors';

const styles = StyleSheet.create({
reactions: {
width: 32,
height: 32,
borderRadius: 32 / 2,
borderWidth: 1,
backgroundColor: '#89CFF0', //different per emoji reaction
borderColor: 'white',
marginTop: 10,
marginRight: -5, // -10
overflow: 'hidden',
justifyContent: 'center',
paddingLeft: 4,
},
reactionText: {
color: colors.grey,
},
reactionNumber: {
marginLeft: 16,
marginTop: 16,
},
});

export default styles;
Loading

0 comments on commit 70b0844

Please sign in to comment.