Skip to content

Commit

Permalink
reaction styling
Browse files Browse the repository at this point in the history
  • Loading branch information
emilysunaryo committed Apr 22, 2024
1 parent f4390dc commit 72dbfdd
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 45 deletions.
55 changes: 55 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
"@emotion/styled": "^11.11.0",
"@expo-google-fonts/manrope": "^0.2.3",
"@expo/vector-icons": "^13.0.0",
"@fortawesome/fontawesome-svg-core": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-native-fontawesome": "^0.3.0",
"@mui/icons-material": "^5.14.13",
"@mui/material": "^5.14.13",
"@mui/styled-engine-sc": "^6.0.0-alpha.1",
Expand Down
10 changes: 7 additions & 3 deletions src/app/(tabs)/genre/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Stack } from 'expo-router';

import { FilterContextProvider } from '../../../utils/FilterContext';

function StackLayout() {
return (
<Stack>
<Stack.Screen name="index" options={{ headerShown: false }} />
</Stack>
<FilterContextProvider>
<Stack>
<Stack.Screen name="index" options={{ headerShown: false }} />
</Stack>
</FilterContextProvider>
);
}

Expand Down
22 changes: 20 additions & 2 deletions src/app/(tabs)/genre/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ import { SafeAreaView } from 'react-native-safe-area-context';

import styles from './styles';
import BackButton from '../../../components/BackButton/BackButton';
import FilterModal, {
CATEGORIES as FilterCategories,
} from '../../../components/FilterModal/FilterModal';
import GenreStoryPreviewCard from '../../../components/GenreStoryPreviewCard/GenreStoryPreviewCard';
import { fetchGenreStoryPreviews, fetchGenres } from '../../../queries/genres';
import { fetchStoryPreviewById } from '../../../queries/stories';
import { StoryPreview, GenreStories, Genre } from '../../../queries/types';
import globalStyles from '../../../styles/globalStyles';

//TODO figure out the logic for the tone and topic dropdowns, especially when we're dealing with multiselect on both parts
import { TagFilter, useFilter } from '../../../utils/FilterContext';

function GenreScreen() {
const { filters } = useFilter();
const [genreStoryInfo, setGenreStoryInfo] = useState<GenreStories[]>();
const [genreStoryIds, setGenreStoryIds] = useState<string[]>([]);
const [subgenres, setSubgenres] = useState<string[]>([]);
Expand Down Expand Up @@ -148,6 +151,21 @@ function GenreScreen() {
getGenre();
}, [genreName]);

const flattenenedFilters = Array.from(filters)
.map(([id, parent]) => [...parent.children, parent as TagFilter])
.flat();
const activeFilterNames = flattenenedFilters.filter(({ active }) => active);

const activeGenreNames = activeFilterNames
.filter(({ category }) => category == FilterCategories.GENRE)
.map(({ name }) => name);
const activeToneNames = activeFilterNames
.filter(({ category }) => category == FilterCategories.TONE)
.map(({ name }) => name);
const activeTopicNames = activeFilterNames
.filter(({ category }) => category == FilterCategories.TOPIC)
.map(({ name }) => name);

useEffect(() => {
const showAllStoryPreviews = async () => {
if (genreStoryIds.length > 0) {
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 @@ -7,6 +7,7 @@ import styles from './styles';
import Icon from '../../../../assets/icons';
import ContentCard from '../../../components/ContentCard/ContentCard';
import PreviewCard from '../../../components/PreviewCard/PreviewCard';
import ReactionPicker from '../../../components/ReactionPicker/ReactionPicker';
import RecentSearchCard from '../../../components/RecentSearchCard/RecentSearchCard';
import { fetchUsername } from '../../../queries/profiles';
import {
Expand Down Expand Up @@ -113,6 +114,7 @@ function HomeScreen() {
<Text style={[globalStyles.h3, styles.subheading]}>
Recommended For You
</Text>
<ReactionPicker />
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
Expand Down
6 changes: 6 additions & 0 deletions src/app/(tabs)/story/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { faHeart as farHeart } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
import { useLocalSearchParams, router } from 'expo-router';
import React, { useEffect, useState } from 'react';
import {
Expand All @@ -15,6 +17,7 @@ import { RenderHTML } from 'react-native-render-html';
import { SafeAreaView } from 'react-native-safe-area-context';

import styles from './styles';
import ReactionPicker from '../../../components/ReactionPicker/ReactionPicker';
import { fetchStory } from '../../../queries/stories';
import { Story } from '../../../queries/types';

Expand Down Expand Up @@ -146,6 +149,9 @@ function StoryScreen() {
>
<Text style={styles.backToTopButtonText}>Back To Top</Text>
</Button>
<View style={styles.bottomReactionContainer}>
<ReactionPicker />
</View>
</ScrollView>
)}
</SafeAreaView>
Expand Down
4 changes: 4 additions & 0 deletions src/app/(tabs)/story/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ const styles = StyleSheet.create({
textAlign: 'left',
color: 'black',
},
bottomReactionContainer: {
flex: 1,
justifyContent: 'space-around',
},
});

export default styles;
27 changes: 27 additions & 0 deletions src/components/FilterModal/ChildFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { CheckBox } from '@rneui/themed';
import { memo } from 'react';

type ChildFilterProps = {
id: number;
name: string;
checked: boolean;
onPress: (id: number) => void;
};

function ChildFilter({ id, name, checked, onPress }: ChildFilterProps) {
return (
<CheckBox
textStyle={{ color: 'purple' }}
key={id}
title={name}
checked={checked}
onPress={() => onPress(id)}
iconType="material-community"
checkedIcon="checkbox-marked"
uncheckedIcon="checkbox-blank-outline"
checkedColor="black"
/>
);
}

export default memo(ChildFilter);
90 changes: 51 additions & 39 deletions src/components/FilterModal/FilterModal.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,47 @@
import { BottomSheet, CheckBox } from '@rneui/themed';
import { useState } from 'react';
import { useCallback, useState } from 'react';
import { View, Text, ScrollView, Pressable } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';

import 'react-native-gesture-handler';
import ChildFilter from './ChildFilter';
import ParentFilter from './ParentFilter';
import styles from './styles';
import Icon from '../../../assets/icons';
import { TagFilter, useFilter } from '../../utils/FilterContext';

type FilterModalProps = {
isVisible: boolean;
setIsVisible: React.Dispatch<React.SetStateAction<boolean>>;
title: string;
};

export enum CATEGORIES {
GENRE = 'genre-medium',
TOPIC = 'topic',
TONE = 'tone',
}

function FilterModal({ isVisible, setIsVisible, title }: FilterModalProps) {
const [checked1, toggleChecked1] = useState(false);
const [checked2, toggleChecked2] = useState(false);
const [checked3, toggleChecked3] = useState(false);
const { dispatch, filters } = useFilter();

const genres = [
{
title: 'Fiction',
state: checked1,
setState: toggleChecked1,
const toggleParentFilter = useCallback(
(id: number) => {
dispatch({ type: 'TOGGLE_MAIN_GENRE', mainGenreId: id });
},
{
title: 'Erasure & Found Poetry',
state: checked2,
setState: toggleChecked2,
},
{
title: 'Non-Fiction',
state: checked3,
setState: toggleChecked3,
[dispatch],
);

const toggleChildFilter = useCallback(
(id: number) => {
dispatch({ type: 'TOGGLE_FILTER', id });
},
];
[dispatch],
);

return (
<SafeAreaProvider>
<BottomSheet
modalProps={{}}
isVisible={isVisible}
containerStyle={styles.modalBackground}
scrollViewProps={{ bounces: false }}
Expand All @@ -54,26 +56,36 @@ function FilterModal({ isVisible, setIsVisible, title }: FilterModalProps) {
</View>
<View style={styles.textContainer}>
<Text style={styles.modalTitle}> {title} </Text>
<ScrollView
showsVerticalScrollIndicator
bounces={false}
style={styles.scrollView}
>
{genres.map(item => {
<FlatList
data={Array.from(filters)}
renderItem={({ item }) => {
const [_, parentFilter] = item;
return (
<CheckBox
key={item.title}
title={item.title}
checked={item.state}
onPress={() => item.setState(!item.state)}
iconType="material-community"
checkedIcon="checkbox-marked"
uncheckedIcon="checkbox-blank-outline"
checkedColor="black"
/>
<>
<ParentFilter
id={parentFilter.id}
name={parentFilter.name}
checked={parentFilter.active}
onPress={toggleParentFilter}
/>

<FlatList
data={parentFilter.children}
renderItem={({ item }) => {
return (
<ChildFilter
id={item.id}
name={item.name}
checked={item.active}
onPress={toggleChildFilter}
/>
);
}}
/>
</>
);
})}
</ScrollView>
}}
/>
</View>
</View>
</BottomSheet>
Expand Down
26 changes: 26 additions & 0 deletions src/components/FilterModal/ParentFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { CheckBox } from '@rneui/themed';
import { memo } from 'react';

type ParentFilterProps = {
id: number;
name: string;
checked: boolean;
onPress: (id: number) => void;
};

function ParentFilter({ id, name, checked, onPress }: ParentFilterProps) {
return (
<CheckBox
key={id}
title={name}
checked={checked}
onPress={() => onPress(id)}
iconType="material-community"
checkedIcon="checkbox-marked"
uncheckedIcon="checkbox-blank-outline"
checkedColor="black"
/>
);
}

export default memo(ParentFilter);
Loading

0 comments on commit 72dbfdd

Please sign in to comment.