Skip to content

Commit

Permalink
Feed list. Share with params for each feed item (#36)
Browse files Browse the repository at this point in the history
* Feed list. Share with params for each feed item

* Video Player Component (#37)

* Video Player Component
Fixes #24

* fixed video and poster contain, volume control

* custom nute/unmute button for video

* adjust lint rules (#38)

* Session Page (#39)

* Session Page
Fixes #30

* update icon color on dark mode

* added paddings, text contrasts and image fixes

* Filter Modal (#43)

* Filter Modal
Fixes #20

* added ability to select multiple filters

* modal bottom padding

* update type safety

* updated modal height constants

* Feat sessions screen (#44)

* first bad batch

* make initial commit

* make initial commit

* [feat] : add icon switch

* [feat] : make initial commit

* [feat] : change color to rgba

* [remove] : unused component

* [feat] : use new StyledSwitch component

* [enhancement] : use new StyledSwitch component

* [feat] : add more tests

* [feat] : renders different cards based on props

* [feat] : add SessionsListVertical for Sessions screen

* [feat] : cater for SessionsListCard

* [feat] : show speakers

* make initial commit

* [fix] : passing correct data type

* [enhancement] : add index to flatlist ItemSeparatorComponent props

* [enhancement] : separate renderItemSeparator

* [feat] : add helper function for time

* [enhancement] : list card component styling

* [feat] : add functions to toggle view

* [fix] : some inconsistencies

* [feat] : add getScheduleTimeAndLocation function

* [feat] : add IDateForDayButton interface

* [fix] : render item separator together with SessionCard

* [enhancement]: use new helper functions

* [enhancement] : change TouchableOpacity to TouchableWithoutFeedback

* [feat] : add handlePress function

* [feat] : show dates from schedule data

* [enhancement] : fine tune sessions

* [feat] : add bottom margin

* [enhancement] : fine tune session card content

* [fix]: order of showing labels

* [feat] : add show mysessions functionality

* [enhancement] : styledSwitch width and height

* [feat] : edit marginHorizontal

* [fix] : tests

* [fix] : revert color in theme and remove comments

* Update app/(app)/home/sessions.tsx

Suggestion by @kharioki to change iconSwitch label based on showsBookmarked state

Co-authored-by: Tony Kharioki <[email protected]>

* [feat] : add line to make validate command run

* [fix] : change avatar img border color

* [fix] : prettier styling

* [enhancement] : set dates directly

* [feat] : set isActive false so that button isn't disabled

* [feat] : add route link to speaker screen when you tap on speaker avatar

* [enhancement] : types for different variations of the card

* [fix] : remove unused function declaration

* [fix] : add screen property to SessionCard

* [fix] : handle scenarios where room is undefined

* - Remove the string type infering on getSuffixForDate helper function
- Make session card disabled when session url is empty

* [fix] : add functionality to handle scenarios theres no sessions

* [enhancement] : changing timing function to spring function and destructure switchAnimation

* [fix] : remove type assertions on room

* [fix] : how room is rendered

* [enhancement] : use expo Link instead of router

* [enhancement] : change pathname to dynamic [speaker]  file

* [enhancement] : pass speaker instead of the whole speaker object

* [fix] : add room label

---------

Co-authored-by: Tony Kharioki <[email protected]>

* Speakers Page and <SpeakerCard /> (#45)

* Speakers Page and <SpeakerCard />
Fixes #23

* resolved centered text, abstracted function

* About Page (#46)

* About Page
Fixes #21

* [feat] : add organizingTeam mock data

* [fix] : OrganizingTeam data

* [refactor] : use content from OrganizingTeam mock data

* [enhancement] : filter organizers to individuals only

* routing to speaker page

* refactor organizer cards

* fixed device width on android

* use local asset for about page

* optimize virtualized list

* testing flashlist

* [fix] : remove placeholder

---------

Co-authored-by: brianwachira <[email protected]>

* Upgrade to Expo SDK 49 (#50)

* [chore]: setting up the SplashScreen (#48)

* [chore]: setting up the SplashScreen

* [chore]: splash.png image

* [chore]: splash.png image

* [fix]: added the .idea/ folder to .gitignore

* [chore]: splash.png image

* Delete .idea directory

* [chore]: made SplashScreen.preventAutoHideAsync() be a global scope

* [chore]: fix prettier issues in app.json

* [fix]: test not running

* [chore]: fixing issues on my branch

* [chore]: fixing issues on my branch

* Delete android directory

* Update .gitignore

* updated .gitignore

---------

Co-authored-by: Tony Kharioki <[email protected]>

* Feature/feedback page (#47)

* [enhancement]: add placeholder color and type

* [feat] disable default header, use header in page

* Feedback banner svg component

* FeedBack page initial markup and styles

* feat: inital modal setup

* [chore]: confetti asset

* add extra styles and types
- feedback input border color
- feedback header background color

* add Feedback Banner Svg

* [feat]: add feedback button component

* [feat]: Feedback Rating button test

* [feat]: add Feedback page component

* [feat]: add feedback modal.

* [fix] move submit button to component

* [fix] move back button to component

* [feat] add onSelected styling

* [fix] move pressables to  components

* [fix] use correct padding size

* [fix] use corrct text size

* [fix] use space component to add spacing

* [fix] add onSelected prop

* [chore] style cleanup and refactor

* [feat] add test for button components
- BackNavigationButton
- SubmitFeedbackButton

* [refactor] add onselected prop

* [fix] use expo image component

* [fix] change styling to camelcase

* [fix] use stack screen header component

* [feat] add modal tint

* [feat] add Banner Images

* [fix] use image background component

* [fix] improve styling and add image properties

* [chore]

* fixed feedback page imagebackground

---------

Co-authored-by: Tony Kharioki <[email protected]>

* Feed list. Share with params for each feed item

* merge fix

* feedlist fixes

* packages

* bottomsheet snappoints

* type fix

* order recent first

* resolved fixes

---------

Co-authored-by: Tony Kharioki <[email protected]>
Co-authored-by: Antony Sande <[email protected]>
Co-authored-by: brianwachira <[email protected]>
Co-authored-by: Amos Nyaburi <[email protected]>
Co-authored-by: George <[email protected]>
  • Loading branch information
6 people authored Oct 7, 2023
1 parent 13c1db4 commit 3855082
Show file tree
Hide file tree
Showing 14 changed files with 10,897 additions and 269 deletions.
Empty file added .env.development
Empty file.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,12 @@ ios/

expo-env.d.ts
# @end expo-cli

# env
.env*.local
.env*.development
.env

# debug files
yarn-debug.*
yarn-error.*
26 changes: 26 additions & 0 deletions __tests__/components/lists/FeedList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { render } from '@testing-library/react-native';
import React from 'react';
import FeedList from '../../../components/lists/FeedList';
import { Feed as FeedData } from '../../../mock/feed';

jest.mock('expo-router');

describe('FeedList', () => {
it('renders the feed list correctly', () => {
const { getAllByTestId } = render(<FeedList />);

// Ensure that all feed items are rendered
const feedItems = getAllByTestId('feedItem');
expect(feedItems.length).toBe(FeedData.data.length);
});

it('renders the feed item with the correct data', () => {
const { getByText } = render(<FeedList />);

// Check if each feed item is rendered with the correct data
FeedData.data.forEach((feed) => {
const feedItem = getByText(feed.body);
expect(feedItem).toBeTruthy();
});
});
});
2 changes: 2 additions & 0 deletions app/(app)/home/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useTheme } from '@react-navigation/native';
import { Tabs } from 'expo-router';
import React from 'react';
import CogIcon from '../../../assets/artworks/CogIcon';
import HeaderRight from '../../../components/headers/HeaderRight';
import MainHeader from '../../../components/headers/MainHeader';

export default () => {
Expand Down Expand Up @@ -57,6 +58,7 @@ export default () => {
},
headerTitleAlign: 'left',
headerTitle: () => <MainHeader />,
headerRight: () => <HeaderRight handlePress={() => {}} />,
}}
/>
<Tabs.Screen
Expand Down
2 changes: 1 addition & 1 deletion app/(app)/home/feed/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export default function Layout() {
const { BottomSheet } =
require('../../../../bottomsheet/bottom-sheet') as typeof import('../../../../bottomsheet/bottom-sheet');

return <BottomSheet />;
return <BottomSheet screenOptions={{ snapPoints: [200, '100%'] }} />;
}
25 changes: 10 additions & 15 deletions app/(app)/home/feed/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
import { Link } from 'expo-router';
import React from 'react';
import { View } from 'react-native';
import StyledText from '../../../../components/common/StyledText';
import { StyleSheet, View } from 'react-native';
import MainContainer from '../../../../components/container/MainContainer';

// TODO: implement feed page
/**
* TASKS:
* - should render the feed list component. Check out the starter code component in components/list folder.
* - use data from mock/feed.ts
*/
import FeedList from '../../../../components/lists/FeedList';

export default function Page() {
return (
<MainContainer>
<MainContainer style={styles.main}>
<View>
<StyledText>Sheet</StyledText>
<Link href="/home/feed/share">
<StyledText>Open Share bottomsheet</StyledText>
</Link>
<FeedList />
</View>
</MainContainer>
);
}

const styles = StyleSheet.create({
main: {
paddingHorizontal: 0,
},
});
5 changes: 2 additions & 3 deletions app/(app)/home/feed/share.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FontAwesome } from '@expo/vector-icons';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { useTheme } from '@react-navigation/native';
import { Link } from 'expo-router';
import React from 'react';
Expand All @@ -16,12 +16,11 @@ import BottomSheetContainer from '../../../../components/container/BottomSheetCo

export default function Share() {
const { colors } = useTheme();

return (
<BottomSheetContainer style={[styles.main, { backgroundColor: colors.background }]}>
<Row>
<Row>
<FontAwesome name="share" size={20} color={colors.text} />
<MaterialCommunityIcons name="share" size={20} color={colors.text} />
<View style={styles.gap} />
<StyledText size="md">Share</StyledText>
</Row>
Expand Down
16 changes: 13 additions & 3 deletions components/container/MainContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useTheme } from '@react-navigation/native';
import type { StatusBarProps } from 'expo-status-bar';
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import type { KeyboardAvoidingViewProps, ScrollViewProps } from 'react-native';
import type { KeyboardAvoidingViewProps, ScrollViewProps, StyleProp, ViewStyle } from 'react-native';
import { KeyboardAvoidingView, Platform, ScrollView, StyleSheet, View } from 'react-native';
import type { Edge, SafeAreaViewProps } from 'react-native-safe-area-context';
import { SafeAreaProvider, SafeAreaView, initialWindowMetrics } from 'react-native-safe-area-context';
Expand All @@ -14,6 +14,7 @@ interface BaseScreenProps {
keyboardOffset?: number;
KeyboardAvoidingViewProps?: KeyboardAvoidingViewProps;
safeAreaEdges?: Array<Edge>;
style?: StyleProp<ViewStyle>;
}

interface FixedScreenProps extends BaseScreenProps {
Expand Down Expand Up @@ -62,17 +63,26 @@ function ScreenWithScrolling(props: ScreenProps) {
const MainContainer = (props: ScreenProps) => {
const { colors, dark } = useTheme();

const { SafeAreaViewProps, StatusBarProps, safeAreaEdges, keyboardOffset = 0, KeyboardAvoidingViewProps } = props;
const {
SafeAreaViewProps,
StatusBarProps,
safeAreaEdges,
keyboardOffset = 0,
KeyboardAvoidingViewProps,
style,
} = props;

const backgroundColor = dark ? colors.bg : colors.background;

const statusBarStyle = dark ? 'light' : 'dark';

const Wrapper = safeAreaEdges?.length ? SafeAreaView : View;

const wrapperStyles = StyleSheet.compose(styles.container, style);

return (
<SafeAreaProvider testID="main-container" initialMetrics={initialWindowMetrics}>
<Wrapper edges={safeAreaEdges} {...SafeAreaViewProps} style={[{ backgroundColor }, styles.container]}>
<Wrapper edges={safeAreaEdges} {...SafeAreaViewProps} style={[{ backgroundColor }, wrapperStyles]}>
<StatusBar style={statusBarStyle} {...StatusBarProps} />

<KeyboardAvoidingView
Expand Down
118 changes: 110 additions & 8 deletions components/lists/FeedList.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,117 @@
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { useTheme } from '@react-navigation/native';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { Image } from 'expo-image';
import { Link } from 'expo-router';
import React from 'react';
import { View } from 'react-native';
import { Dimensions, StyleSheet, View } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
import { blurhash } from '../../config/constants';
import { Feed as FeedData } from '../../mock/feed';
import Row from '../common/Row';
import StyledText from '../common/StyledText';

// TODO: - Implement a feed list-view of feeds as seen in the design
/**
* - order the feeds to most recent first
* - clicking on the share button on each feed should open the bottom-sheet and pass params to the bottom-sheet - only implement this part if you’re comfortable working with bottomsheet
* - add tests for the feed list component
*/
dayjs.extend(relativeTime);

interface FeedListItemProps {
item: Feed;
}

type Feed = {
title: string;
body: string;
topic: string;
url: string;
image: string;
created_at: string;
};

const { height } = Dimensions.get('screen');

const FeedListItem = ({ item }: FeedListItemProps) => {
const { colors } = useTheme();
return (
<View style={[styles.feed, { borderBottomColor: colors.border }]} testID="feedItem">
<StyledText size="md" font="regular">
{item.body}
</StyledText>
<View style={styles.imageContainer}>
<Image
style={styles.image}
source={{ uri: item.image }}
transition={1000}
contentFit="cover"
placeholder={blurhash}
/>
</View>

<Row>
<Link
href={{
pathname: '/home/feed/share',
}}
>
<View style={styles.share}>
<StyledText size="md" allowFontScaling font="bold" variant="link" style={styles.shareLabel}>
Share
</StyledText>
<MaterialCommunityIcons size={20} name="share" color={colors.primary} />
</View>
</Link>

<StyledText size="sm">{dayjs(item.created_at).fromNow()}</StyledText>
</Row>
</View>
);
};

const FeedList = () => {
return <View />;
const recentFirst = (data: Array<Feed>) => {
return data.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
};

return (
<View style={styles.main}>
<FlatList
showsVerticalScrollIndicator={false}
data={recentFirst(FeedData.data)}
keyExtractor={(item) => item.title}
renderItem={({ item }: { item: Feed }) => {
return <FeedListItem item={item} key={item.title} />;
}}
/>
</View>
);
};

export default FeedList;

const styles = StyleSheet.create({
main: {
paddingBottom: 20,
},
feed: {
marginVertical: 8,
borderBottomWidth: 1,
padding: 12,
},
image: {
height: height * 0.23,
borderRadius: 8,
},
imageContainer: {
borderRadius: 8,
marginVertical: 8,
overflow: 'hidden',
},
share: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 8,
},
shareLabel: {
marginRight: 6,
},
});
9 changes: 1 addition & 8 deletions global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,7 @@ export type Typography = {
};

export interface IFeed {
data: Array<{
title: string;
body: string;
topic: string;
url: string;
image: string;
created_at: string;
}>;
data: Array<Feed>;
meta: Meta;
}

Expand Down
4 changes: 2 additions & 2 deletions mock/feed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ export const Feed: IFeed = {
},
{
title: 'droidconKe Ticket sales',
body: 'This 4th in-person event will include several tech communities from the East African Region and continental members. Participants will have an excellent chance to learn about Android development and opportunities and to network with Android experts in the ecosystem.',
body: 'This 4th in-person event will include several tech communities from the East African Region and continental members. Participants will have an excellent chance to learn about Android development and opportunities and to network with Android expert in the ecosystem.',
topic: 'droidconke-2022-281',
url: 'https://droidcon.co.ke/',
image:
'https://res.cloudinary.com/droidconke/image/upload/v1684788047/prod/upload/event/feeds/qhk1umslrdkqmmfklqsn.png',
'https://res.cloudinary.com/droidconke/image/upload/v1684788565/prod/upload/event/feeds/r0gtvnh2qtfy0rnkoxwq.png',
created_at: '2023-05-22 23:40:48',
},
],
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
"@shopify/flash-list": "1.4.3",
"@th3rdwave/react-navigation-bottom-sheet": "0.2.7",
"@types/react": "~18.2.14",
"expo": "^49.0.11",
"dayjs": "^1.11.10",
"expo": "^49.0.0",
"expo-av": "~13.4.1",
"expo-constants": "~14.4.2",
"expo-font": "~11.4.0",
"expo-image": "~1.3.2",
"expo-image": "~1.3.4",
"expo-linking": "~5.0.2",
"expo-router": "^2.0.0",
"expo-splash-screen": "~0.20.5",
Expand Down
Loading

0 comments on commit 3855082

Please sign in to comment.