Merge pull request #1819 from ecency/revert-search

revert search
This commit is contained in:
Feruz M 2021-01-07 11:21:12 +02:00 committed by GitHub
commit 29da48f8fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 650 additions and 0 deletions

View File

@ -0,0 +1,80 @@
import React, { useState } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { useIntl } from 'react-intl';
import styles from './communitiesListItemStyles';
import { Tag } from '../../../components/basicUIElements';
const UserListItem = ({
index,
handleOnPress,
handleOnLongPress,
title,
about,
admins,
id,
authors,
posts,
subscribers,
isNsfw,
name,
handleSubscribeButtonPress,
isSubscribed,
isLoggedIn,
}) => {
const [subscribed, setSubscribed] = useState(isSubscribed);
const intl = useIntl();
const _handleSubscribeButtonPress = () => {
handleSubscribeButtonPress({ subscribed: !subscribed, communityId: name }).then(() => {
setSubscribed(!subscribed);
});
};
return (
<TouchableOpacity
onLongPress={() => handleOnLongPress && handleOnLongPress()}
onPress={() => handleOnPress && handleOnPress(name)}
>
<View style={[styles.itemWrapper, index % 2 !== 0 && styles.itemWrapperGray]}>
<View style={styles.content}>
<View style={styles.header}>
<Text style={styles.title}>{title}</Text>
{isLoggedIn && (
<Tag
style={styles.subscribeButton}
textStyle={subscribed && styles.subscribeButtonText}
value={
!subscribed
? intl.formatMessage({
id: 'search_result.communities.subscribe',
})
: intl.formatMessage({
id: 'search_result.communities.unsubscribe',
})
}
isPin={!subscribed}
isFilter
onPress={_handleSubscribeButtonPress}
/>
)}
</View>
{!!about && <Text style={styles.about}>{about}</Text>}
<View style={styles.separator} />
<Text style={styles.stats}>
{`${subscribers.toString()} ${intl.formatMessage({
id: 'search_result.communities.subscribers',
})} ${authors.toString()} ${intl.formatMessage({
id: 'search_result.communities.posters',
})} ${posts} ${intl.formatMessage({
id: 'search_result.communities.posts',
})}`}
</Text>
</View>
</View>
</TouchableOpacity>
);
};
export default UserListItem;

View File

@ -0,0 +1,108 @@
import React from 'react';
import { useIntl } from 'react-intl';
import { FlatList, View, Text, TouchableOpacity } from 'react-native';
import get from 'lodash/get';
// Components
import { FilterBar, UserAvatar } from '../../../components';
import CommunitiesList from './communitiesList';
import { CommunitiesPlaceHolder } from '../../../components/basicUIElements';
import CommunitiesContainer from '../container/communitiesContainer';
import styles from './otherResultsStyles';
import DEFAULT_IMAGE from '../../../assets/no_image.png';
import Tag from '../../../components/basicUIElements/view/tag/tagView';
const filterOptions = ['my', 'rank', 'subs', 'new'];
const CommunitiesScreen = ({ navigation, searchValue }) => {
const intl = useIntl();
const activeVotes = get(navigation, 'state.params.activeVotes');
const _renderEmptyContent = () => {
return (
<>
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
</>
);
};
return (
<CommunitiesContainer data={activeVotes} searchValue={searchValue}>
{({
data,
filterIndex,
allSubscriptions,
handleOnVotersDropdownSelect,
handleOnPress,
handleSubscribeButtonPress,
isLoggedIn,
noResult,
}) => (
<>
<FilterBar
dropdownIconName="arrow-drop-down"
options={filterOptions.map((item) =>
intl.formatMessage({
id: `search_result.communities_filter.${item}`,
}),
)}
defaultText={intl.formatMessage({
id: `search_result.communities_filter.${filterOptions[filterIndex]}`,
})}
selectedOptionIndex={filterIndex}
onDropdownSelect={(index) => handleOnVotersDropdownSelect(index, filterOptions[index])}
/>
{filterIndex !== 0 && (
<CommunitiesList
votes={data}
allSubscriptions={allSubscriptions}
handleOnPress={handleOnPress}
handleSubscribeButtonPress={handleSubscribeButtonPress}
isLoggedIn={isLoggedIn}
noResult={noResult}
/>
)}
{filterIndex === 0 && allSubscriptions && allSubscriptions.length > 0 && (
<FlatList
data={allSubscriptions}
//keyExtractor={(item, ind) => `${item}-${ind}`}
renderItem={({ item, index }) => (
<View style={[styles.communityWrapper, index % 2 !== 0 && styles.itemWrapperGray]}>
<View style={{ flex: 3, flexDirection: 'row', alignItems: 'center' }}>
<TouchableOpacity onPress={() => handleOnPress(item[0])}>
<UserAvatar username={item[0]} defaultSource={DEFAULT_IMAGE} noAction />
</TouchableOpacity>
<TouchableOpacity onPress={() => handleOnPress(item[0])}>
<Text style={styles.community}>{item[1]}</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 1 }}>
<Tag
style={styles.subscribeButton}
textStyle={styles.subscribeButtonText}
value={intl.formatMessage({
id: 'search_result.communities.unsubscribe',
})}
isPin={false}
isFilter
onPress={() =>
handleSubscribeButtonPress({ isSubscribed: true, communityId: item[0] })
}
/>
</View>
</View>
)}
ListEmptyComponent={_renderEmptyContent}
/>
)}
</>
)}
</CommunitiesContainer>
);
};
export default CommunitiesScreen;

View File

@ -0,0 +1,70 @@
import React from 'react';
import { SafeAreaView, FlatList } from 'react-native';
// Components
import CommunitiesListItem from './CommunitiesListItem';
import { CommunitiesPlaceHolder } from '../../../components/basicUIElements';
// Styles
import styles from './communitiesListStyles';
const CommunitiesList = ({
votes,
handleOnPress,
handleSubscribeButtonPress,
allSubscriptions,
isLoggedIn,
noResult,
}) => {
const _renderItem = ({ item, index }) => {
const isSubscribed = allSubscriptions.some((sub) => sub[0] === item.name);
return (
<CommunitiesListItem
index={index}
title={item.title}
about={item.about}
admins={item.admins}
id={item.id}
authors={item.num_authors}
posts={item.num_pending}
subscribers={item.subscribers}
isNsfw={item.is_nsfw}
name={item.name}
handleOnPress={handleOnPress}
handleSubscribeButtonPress={handleSubscribeButtonPress}
isSubscribed={isSubscribed}
isLoggedIn={isLoggedIn}
/>
);
};
const _renderEmptyContent = () => {
return (
<>
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
</>
);
};
return (
<SafeAreaView style={styles.container}>
{!noResult && (
<FlatList
data={votes}
keyExtractor={(item) => item.id && item.id.toString()}
renderItem={_renderItem}
ListEmptyComponent={_renderEmptyContent}
/>
)}
</SafeAreaView>
);
};
export default CommunitiesList;

View File

@ -0,0 +1,62 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
padding: 8,
flexDirection: 'row',
},
content: {
flexDirection: 'column',
marginLeft: 8,
width: '100%',
},
itemWrapper: {
alignItems: 'center',
padding: 16,
borderRadius: 8,
flexDirection: 'row',
backgroundColor: '$primaryBackgroundColor',
},
itemWrapperGray: {
backgroundColor: '$primaryLightBackground',
},
title: {
color: '$primaryBlue',
fontSize: 17,
fontWeight: 'bold',
fontFamily: '$primaryFont',
},
about: {
fontSize: 14,
fontFamily: '$primaryFont',
marginTop: 5,
paddingTop: 10,
color: '$primaryBlack',
},
separator: {
width: 100,
alignSelf: 'center',
backgroundColor: '$primaryDarkGray',
height: 1,
marginVertical: 10,
},
stats: {
fontSize: 14,
fontFamily: '$primaryFont',
color: '$primaryDarkGray',
paddingBottom: 10,
},
subscribeButton: {
borderWidth: 1,
maxWidth: 75,
borderColor: '$primaryBlue',
},
subscribeButtonText: {
textAlign: 'center',
color: '$primaryBlue',
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
},
});

View File

@ -0,0 +1,16 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
flex: 1,
padding: 8,
marginBottom: 40,
flexDirection: 'row',
backgroundColor: '$primaryBackgroundColor',
},
text: {
color: '$iconColor',
fontSize: 12,
fontFamily: '$primaryFont',
},
});

View File

@ -0,0 +1,107 @@
import React from 'react';
import { SafeAreaView, FlatList, View, Text, TouchableOpacity } from 'react-native';
import { useIntl } from 'react-intl';
// Components
import { FilterBar, UserAvatar } from '../../../components';
import { CommunitiesPlaceHolder } from '../../../components/basicUIElements';
import OtherResultContainer from '../container/otherResultContainer';
import styles from './otherResultsStyles';
import DEFAULT_IMAGE from '../../../assets/no_image.png';
const filterOptions = ['user', 'tag'];
const OtherResult = ({ navigation, searchValue }) => {
const intl = useIntl();
const _renderUserItem = (item, index) => (
<View style={[styles.itemWrapper, index % 2 !== 0 && styles.itemWrapperGray]}>
<UserAvatar username={item} defaultSource={DEFAULT_IMAGE} noAction />
<Text style={styles.username}>{item}</Text>
</View>
);
const _renderTagItem = (item, index) => (
<View style={[styles.itemWrapper, index % 2 !== 0 && styles.itemWrapperGray]}>
<Text style={styles.username}>{`#${item.name}`}</Text>
</View>
);
const _renderEmptyContent = () => {
return (
<>
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
</>
);
};
const _renderList = (users, tags, filterIndex, handleOnPress) => {
switch (filterIndex) {
case 0:
if (users && users.length > 0) {
return (
<FlatList
data={users}
keyExtractor={(item, ind) => `${item}-${ind}`}
renderItem={({ item, index }) => (
<TouchableOpacity onPress={() => handleOnPress(item)}>
{_renderUserItem(item, index)}
</TouchableOpacity>
)}
ListEmptyComponent={_renderEmptyContent}
/>
);
}
case 1:
if (tags && tags.length > 0) {
return (
<FlatList
data={tags}
keyExtractor={(item) => `${item.name}+${item.id}+${item.comments}`}
renderItem={({ item, index }) => (
<TouchableOpacity onPress={() => handleOnPress(item)}>
{_renderTagItem(item, index)}
</TouchableOpacity>
)}
ListEmptyComponent={_renderEmptyContent}
/>
);
}
default:
break;
}
};
return (
<OtherResultContainer searchValue={searchValue}>
{({ users, tags, filterIndex, handleFilterChanged, handleOnPress, loadMore }) => (
<SafeAreaView style={styles.container}>
<FilterBar
dropdownIconName="arrow-drop-down"
options={filterOptions.map((item) =>
intl.formatMessage({
id: `search_result.other_result_filter.${item}`,
}),
)}
defaultText={intl.formatMessage({
id: `search_result.other_result_filter.${filterOptions[filterIndex]}`,
})}
selectedOptionIndex={filterIndex}
onDropdownSelect={(index) => handleFilterChanged(index, filterOptions[index])}
/>
{_renderList(users, tags, filterIndex, handleOnPress)}
</SafeAreaView>
)}
</OtherResultContainer>
);
};
export default OtherResult;

View File

@ -0,0 +1,48 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
flex: 1,
backgroundColor: '$primaryBackgroundColor',
},
itemWrapper: {
paddingHorizontal: 16,
paddingTop: 16,
paddingBottom: 8,
borderRadius: 8,
backgroundColor: '$primaryBackgroundColor',
flexDirection: 'row',
alignItems: 'center',
},
itemWrapperGray: {
backgroundColor: '$primaryLightBackground',
},
username: {
marginLeft: 10,
color: '$primaryBlack',
},
communityWrapper: {
paddingHorizontal: 16,
paddingTop: 10,
paddingBottom: 10,
borderRadius: 8,
backgroundColor: '$primaryBackgroundColor',
flexDirection: 'row',
alignItems: 'center',
flex: 1,
},
subscribeButton: {
maxWidth: 75,
borderWidth: 1,
borderColor: '$primaryBlue',
},
subscribeButtonText: {
textAlign: 'center',
color: '$primaryBlue',
},
community: {
justifyContent: 'center',
marginLeft: 15,
color: '$primaryBlack',
},
});

View File

@ -0,0 +1,115 @@
import React from 'react';
import { SafeAreaView, FlatList, View, Text, TouchableOpacity } from 'react-native';
import get from 'lodash/get';
import isUndefined from 'lodash/isUndefined';
import FastImage from 'react-native-fast-image';
import { useIntl } from 'react-intl';
// Components
import { PostHeaderDescription, FilterBar } from '../../../components';
import { TextWithIcon, CommunitiesPlaceHolder } from '../../../components/basicUIElements';
import PostResultContainer from '../container/postResultContainer';
import { getTimeFromNow } from '../../../utils/time';
import styles from './postResultStyles';
import DEFAULT_IMAGE from '../../../assets/no_image.png';
const filterOptions = ['relevance', 'popularity', 'newest'];
const PostResult = ({ navigation, searchValue }) => {
const intl = useIntl();
const _renderItem = (item, index) => {
return (
<View style={[styles.itemWrapper, index % 2 !== 0 && styles.itemWrapperGray]}>
<PostHeaderDescription
date={getTimeFromNow(get(item, 'created_at'))}
name={get(item, 'author')}
reputation={Math.floor(get(item, 'author_rep'))}
size={36}
tag={item.category}
/>
<FastImage source={item.img_url} style={styles.thumbnail} defaultSource={DEFAULT_IMAGE} />
<View style={[styles.postDescription]}>
<Text style={styles.title}>{item.title}</Text>
{!!item.body && (
<Text style={styles.summary} numberOfLines={2}>
{item.body}
</Text>
)}
</View>
<View style={styles.stats}>
{!isUndefined(item.payout) && (
<Text style={styles.postIconText}>{`$ ${item.payout}`}</Text>
)}
<TextWithIcon
iconName="heart-outline"
textStyle={styles.postIconText}
iconStyle={styles.postIcon}
iconType="MaterialCommunityIcons"
text={get(item, 'up_votes', 0)}
/>
<TextWithIcon
iconName="comment-outline"
iconStyle={styles.postIcon}
iconType="MaterialCommunityIcons"
text={get(item, 'children', 0)}
textStyle={styles.postIconText}
/>
</View>
</View>
);
};
const _renderEmptyContent = () => {
return (
<>
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
<CommunitiesPlaceHolder />
</>
);
};
return (
<PostResultContainer searchValue={searchValue}>
{({ data, filterIndex, handleFilterChanged, handleOnPress, loadMore }) => (
<SafeAreaView style={styles.container}>
<FilterBar
dropdownIconName="arrow-drop-down"
options={filterOptions.map((item) =>
intl.formatMessage({
id: `search_result.post_result_filter.${item}`,
}),
)}
defaultText={intl.formatMessage({
id: `search_result.post_result_filter.${filterOptions[filterIndex]}`,
})}
selectedOptionIndex={filterIndex}
onDropdownSelect={(index) => handleFilterChanged(index, filterOptions[index])}
/>
<FlatList
data={data}
keyExtractor={(item) => item.id && item.id.toString()}
renderItem={({ item, index }) => (
<TouchableOpacity onPress={() => handleOnPress(item)}>
{_renderItem(item, index)}
</TouchableOpacity>
)}
onEndReached={loadMore}
ListEmptyComponent={_renderEmptyContent}
ListFooterComponent={<CommunitiesPlaceHolder />}
/>
</SafeAreaView>
)}
</PostResultContainer>
);
};
export default PostResult;

View File

@ -0,0 +1,44 @@
import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
container: {
flex: 1,
backgroundColor: '$primaryBackgroundColor',
},
title: {
fontSize: 16,
fontWeight: 'bold',
marginVertical: 5,
color: '$primaryBlack',
},
summary: {
fontSize: 13,
color: '$primaryDarkGray',
},
itemWrapper: {
paddingHorizontal: 16,
paddingTop: 16,
paddingBottom: 8,
borderRadius: 8,
backgroundColor: '$primaryBackgroundColor',
},
itemWrapperGray: {
backgroundColor: '$primaryLightBackground',
},
stats: {
flexDirection: 'row',
},
postIcon: {
alignSelf: 'flex-start',
fontSize: 20,
color: '$iconColor',
margin: 0,
width: 20,
marginLeft: 25,
},
postIconText: {
color: '$primaryDarkGray',
fontSize: 13,
alignSelf: 'center',
},
});