Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[story] Update story page #93

Merged
merged 20 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions assets/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import { SvgXml } from 'react-native-svg';

export type IconType =
| 'home_outline'
| 'share_outline'
| 'document_outline'
| 'search_outline'
| 'close_modal_button'
| 'red_x'
| 'share_outline'
| 'green_check'
| 'hide_password'
| 'grey_dot'
Expand All @@ -21,6 +23,7 @@ export type IconType =

const IconSvgs: Record<IconType, React.ReactElement> = {
home_outline: <Ionicons name="home-outline" size={23} />,
share_outline: <Ionicons name="share-outline" size={23} color="gray" />,
search_outline: <Ionicons name="search-outline" size={23} />,
document_outline: <Ionicons name="document-outline" size={23} />,
settings_gear: <Ionicons name="settings-outline" size={32} />,
Expand Down
1 change: 1 addition & 0 deletions src/app/(tabs)/genre/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Text,
FlatList,
} from 'react-native';

import { Dropdown, MultiSelect } from 'react-native-element-dropdown';
import { Icon } from 'react-native-elements';
import { TouchableOpacity } from 'react-native-gesture-handler';
Expand Down
249 changes: 103 additions & 146 deletions src/app/(tabs)/story/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { useLocalSearchParams, router } from 'expo-router';
import { router, useLocalSearchParams } from 'expo-router';
import * as cheerio from 'cheerio';
import React, { useEffect, useState } from 'react';
import {
ActivityIndicator,
FlatList,
ScrollView,
Share,
Text,
TouchableOpacity,
View,
useWindowDimensions,
} from 'react-native';
Expand All @@ -16,14 +15,15 @@ import { RenderHTML } from 'react-native-render-html';
import { SafeAreaView } from 'react-native-safe-area-context';

import styles from './styles';
import FavoriteStoryButton from '../../../components/FavoriteStoryButton/FavoriteStoryButton';
import SaveStoryButton from '../../../components/SaveStoryButton/SaveStoryButton';
import Icon from '../../../../assets/icons';
import AuthorImage from '../../../components/AuthorImage/AuthorImage';
import ReactionPicker from '../../../components/ReactionPicker/ReactionPicker';
import BackButton from '../../../components/BackButton/BackButton';
import { fetchStory } from '../../../queries/stories';
import { Story } from '../../../queries/types';
import colors from '../../../styles/colors';
import globalStyles, { fonts } from '../../../styles/globalStyles';
import BackButton from '../../../components/BackButton/BackButton';
import { TouchableOpacity } from 'react-native-gesture-handler';
import OptionBar from '../../../components/OptionBar/OptionBar';

function StoryScreen() {
const [isLoading, setLoading] = useState(true);
Expand All @@ -49,144 +49,98 @@ function StoryScreen() {
});
}, [storyId]);

const onShare = async () => {
try {
const result = await Share.share({
message: `Check out this story from Girls Write Now!!!\n${story.link}/`,
});
if (result.action === Share.sharedAction) {
if (result.activityType) {
// shared with activity type of result.activityType
} else {
// shared
}
} else if (result.action === Share.dismissedAction) {
// dismissed
}
} catch (error) {
console.log(error);
}
};

return (
<SafeAreaView style={[globalStyles.tabBarContainer, styles.container]}>
{isLoading ? (
<ActivityIndicator />
) : (
<ScrollView
bounces
ref={scrollRef}
showsVerticalScrollIndicator={false}
>
<BackButton pressFunction={() => router.back()} />

<Text style={[globalStyles.h1, styles.title]}>{story?.title}</Text>

<TouchableOpacity
onPress={() => {
router.push({
pathname: '/author',
params: { author: story.author_id.toString() },
});
}}
<View>
<ScrollView
stickyHeaderIndices={[5]}
bounces
ref={scrollRef}
showsVerticalScrollIndicator={false}
>
<View style={styles.author}>
<Image
style={styles.authorImage}
source={{ uri: story.author_image ? story.author_image : '' }}
/>
<Text
style={[
globalStyles.subHeading1Bold,
{ textDecorationLine: 'underline' },
]}
>
By {story.author_name}
</Text>
</View>
</TouchableOpacity>

<View>
<FlatList
style={styles.genres}
horizontal
data={story.genre_medium}
renderItem={({ item }) => (
<View style={styles.genresBorder}>
<Text style={[globalStyles.button1, styles.genresText]}>
{item}
</Text>
</View>
<BackButton pressFunction={() => router.back()} />
<View style={styles.container}>
{story?.featured_media ? (
<Image
style={styles.image}
source={{ uri: story.featured_media }}
/>
) : (
<Text>No image available</Text>
)}
</View>

<Text style={[globalStyles.h1, styles.title]}>{story?.title}</Text>

<AuthorImage
author_name={story.author_name}
author_Uri={story.author_image}
author_id={story.author_id.toString()}
/>
<View style={styles.options}>
<SaveStoryButton storyId={parseInt(storyId as string, 10)} />
<FavoriteStoryButton storyId={parseInt(storyId as string, 10)} />
<Button
textColor="black"
buttonColor={colors.gwnOrange}
icon="share"
onPress={onShare}
style={{ width: 125, marginBottom: 16, borderRadius: 10 }}
>
<Text
style={[globalStyles.bodyUnderline, styles.shareButtonText]}
>
Share Story
</Text>
</Button>

<View>
<FlatList
style={styles.genres}
horizontal
showsHorizontalScrollIndicator={false}
data={story.genre_medium}
keyExtractor={(_, index) => index.toString()} // Add a key extractor for performance optimization
renderItem={({ item, index }) => (
<View
style={[
styles.genresBorder,
{
backgroundColor:
index % 2 === 0 ? '#E66E3F' : '#B49BC6',
},
]}
>
<Text style={styles.genresText}>{item}</Text>
</View>
)}
/>
</View>
</View>

<RenderHTML
contentWidth={width}
source={story.excerpt}
baseStyle={{ ...globalStyles.body3, ...styles.excerpt }}
systemFonts={fonts}
/>

<RenderHTML
contentWidth={width}
source={story.content}
baseStyle={{ ...globalStyles.body1, ...styles.story }}
systemFonts={fonts}
/>

<Button
textColor="black"
buttonColor={colors.gwnOrange}
icon="share"
onPress={onShare}
style={{ width: 125, marginBottom: 16, borderRadius: 10 }}
>
<Text style={[globalStyles.bodyUnderline, styles.shareButtonText]}>
Share Story
</Text>
</Button>

<Text style={[globalStyles.h3, styles.authorProcess]}>
Author's Process
</Text>

<RenderHTML
contentWidth={width}
source={story.process}
baseStyle={{ ...globalStyles.body1, ...styles.process }}
systemFonts={fonts}
/>

<TouchableOpacity
onPress={() => {
router.push({
pathname: '/author',
params: { author: story.author_id.toString() },
});
}}
>
<OptionBar
story={story}
storyId={parseInt(storyId as string, 10)}
/>

<RenderHTML
source={{
html: `"${cheerio.load(story.excerpt.html ?? '').text()}"`,
}}
baseStyle={globalStyles.h2}
contentWidth={width}
systemFonts={fonts}
tagsStyles={{ p: globalStyles.h2 }}
ignoredStyles={['color', 'fontSize', 'fontWeight']} // Ignore these inline styles
/>

<View style={{ marginTop: 32 }} />

<RenderHTML
systemFonts={fonts}
source={story.content}
contentWidth={width}
baseStyle={styles.story}
/>

<Text style={styles.authorProcess}>Author's Process</Text>

<RenderHTML
systemFonts={fonts}
source={story.process}
contentWidth={width}
baseStyle={styles.process}
/>

<View style={styles.author}>
<Image
style={styles.authorImage}
source={{ uri: story.author_image ? story.author_image : '' }}
source={{ uri: story.author_image }}
/>
<Text
style={[
Expand All @@ -197,20 +151,23 @@ function StoryScreen() {
By {story.author_name}
</Text>
</View>
</TouchableOpacity>

<Button
textColor="black"
icon="arrow-up"
onPress={scrollUp}
style={{ width: 125, marginBottom: 16, borderRadius: 10 }}
>
<Text style={globalStyles.bodyBoldUnderline}>Back To Top</Text>
</Button>
<View style={styles.bottomReactionContainer}>
<ReactionPicker storyId={parseInt(storyId as string, 10)} />
</View>
</ScrollView>
<OptionBar
story={story}
storyId={parseInt(storyId as string, 10)}
/>

<Button
textColor="black"
icon="arrow-up"
onPress={scrollUp}
style={{ width: 125, marginBottom: 16, borderRadius: 10 }}
>
<Text style={styles.backToTopButtonText}>Back To Top</Text>
</Button>
<View style={styles.bottomReactionContainer} />
</ScrollView>
</View>
)}
</SafeAreaView>
);
Expand Down
Loading
Loading