From 646b179c004f6635bc89fd92b21ccc6f12866022 Mon Sep 17 00:00:00 2001 From: ue Date: Sun, 15 Sep 2019 12:46:25 +0300 Subject: [PATCH] enhanced search added utils for avatar --- .../formInput/view/formInputView.js | 5 +- .../container/searchModalContainer.js | 86 ++++++++++--------- .../searchModal/view/searchModalStyles.js | 2 +- .../searchModal/view/searchModalView.js | 18 ++-- .../userAvatar/view/userAvatarView.js | 9 +- src/utils/image.js | 11 ++- src/utils/postParser.js | 9 +- 7 files changed, 76 insertions(+), 64 deletions(-) diff --git a/src/components/formInput/view/formInputView.js b/src/components/formInput/view/formInputView.js index c86cc9a5c..869f83390 100644 --- a/src/components/formInput/view/formInputView.js +++ b/src/components/formInput/view/formInputView.js @@ -6,6 +6,9 @@ import FastImage from 'react-native-fast-image'; import { TextInput } from '../../textInput'; import { Icon } from '../../icon'; +// Utils +import { getResizedAvatar } from '../../../utils/image'; + // Styles import styles from './formInputStyles'; @@ -80,7 +83,7 @@ class FormInputView extends Component { { const { isConnected } = this.props; - + if (text && text.length < 2) return; + if (this.timer) { + clearTimeout(this.timer); + } if (!isConnected) return; - - if (text && text !== '@' && text !== '#') { - if (text[0] === '@') { - lookupAccounts(text.substr(1)).then(res => { - const users = res.map(item => ({ - image: `https://steemitimages.com/u/${item}/avatar/small`, - text: item, - ...item, - })); - this.setState({ searchResults: { type: 'user', data: users } }); - }); - } else if (text[0] === '#') { - getTrendingTags(text.substr(1)).then(res => { - const tags = res.map(item => ({ - text: `#${item.name}`, - ...item, - })); - - this.setState({ searchResults: { type: 'tag', data: tags } }); - }); - } else { - search({ q: text }).then(res => { - res.results = res.results - .filter(item => item.title !== '') - .map(item => ({ - image: item.img_url || `https://steemitimages.com/u/${item.author}/avatar/small`, - text: item.title, + this.timer = setTimeout(() => { + if (text && text !== '@' && text !== '#') { + if (text[0] === '@') { + lookupAccounts(text.substr(1)).then(res => { + const users = res.map(item => ({ + image: getResizedAvatar(item), + text: item, ...item, })); - this.setState({ searchResults: { type: 'content', data: res.results } }); - }); + this.setState({ searchResults: { type: 'user', data: users } }); + }); + } else if (text[0] === '#') { + getTrendingTags(text.substr(1)).then(res => { + const tags = res.map(item => ({ + text: `#${get(item, 'name', '')}`, + ...item, + })); + + this.setState({ searchResults: { type: 'tag', data: tags } }); + }); + } else { + search({ q: text }).then(res => { + res.results = res.results + .filter(item => item.title !== '') + .map(item => ({ + image: item.img_url || getResizedAvatar(get(item, 'author')), + text: item.title, + ...item, + })); + this.setState({ searchResults: { type: 'content', data: get(res, 'results', []) } }); + }); + } } - } + }, 500); }; _handleOnPressListItem = (type, item) => { @@ -89,24 +93,24 @@ class SearchModalContainer extends PureComponent { switch (type) { case 'user': - routeName = item.text === username ? ROUTES.TABBAR.PROFILE : ROUTES.SCREENS.PROFILE; + routeName = get(item, 'text') === username ? ROUTES.TABBAR.PROFILE : ROUTES.SCREENS.PROFILE; params = { - username: item.text, + username: get(item, 'text'), }; key = item.text; break; case 'content': routeName = ROUTES.SCREENS.POST; params = { - author: item.author, - permlink: item.permlink, + author: get(item, 'author'), + permlink: get(item, 'permlink'), }; - key = item.permlink; + key = get(item, 'permlink'); break; case 'tag': routeName = ROUTES.SCREENS.SEARCH_RESULT; params = { - tag: item.text.substr(1), + tag: get(item, 'text', '').substr(1), }; break; @@ -129,13 +133,13 @@ class SearchModalContainer extends PureComponent { return ( ); } diff --git a/src/components/searchModal/view/searchModalStyles.js b/src/components/searchModal/view/searchModalStyles.js index 7bf7601f7..1cd55d186 100644 --- a/src/components/searchModal/view/searchModalStyles.js +++ b/src/components/searchModal/view/searchModalStyles.js @@ -47,7 +47,7 @@ export default EStyleSheet.create({ marginRight: 24, flex: 1, }, - searhItems: { + searchItems: { marginHorizontal: 30, marginVertical: 10, flexDirection: 'row', diff --git a/src/components/searchModal/view/searchModalView.js b/src/components/searchModal/view/searchModalView.js index e92bf112b..00d8be72c 100644 --- a/src/components/searchModal/view/searchModalView.js +++ b/src/components/searchModal/view/searchModalView.js @@ -1,9 +1,7 @@ import React, { PureComponent } from 'react'; import { View, Text, FlatList, TouchableOpacity, SafeAreaView } from 'react-native'; - import FastImage from 'react-native-fast-image'; - -// Constants +import { get, has } from 'lodash'; // Components import { Modal } from '../..'; @@ -40,7 +38,7 @@ class SearchModalView extends PureComponent { return ( handleOnClose()} + handleOnModalClose={handleOnClose} isFullScreen swipeToClose isTransparent @@ -53,12 +51,14 @@ class SearchModalView extends PureComponent { /> ( // TODO: Make it quick ui component - handleOnPressListItem(searchResults.type, item)}> - + handleOnPressListItem(get(searchResults, 'type'), item)} + > + {item.image && ( - {item.text && {item.text}} + {has(item, 'text') && {item.text}} )} - keyExtractor={(post, index) => index.toString()} + keyExtractor={(item, index) => get(item, 'id', index).toString()} removeClippedSubviews onEndThreshold={0} initialNumToRender={20} diff --git a/src/components/userAvatar/view/userAvatarView.js b/src/components/userAvatar/view/userAvatarView.js index c903ea4d8..37dcdd398 100644 --- a/src/components/userAvatar/view/userAvatarView.js +++ b/src/components/userAvatar/view/userAvatarView.js @@ -9,6 +9,9 @@ import styles from './userAvatarStyles'; // Constants import ROUTES from '../../../constants/routeNames'; +// Utils +import { getResizedAvatar } from '../../../utils/image'; + const DEFAULT_IMAGE = require('../../../assets/avatar_default.png'); /* Props @@ -58,11 +61,7 @@ class UserAvatarView extends Component { let _size; const _avatar = username ? { - uri: - avatarUrl || - (name === username - ? avatar - : `https://steemitimages.com/u/${username}/avatar/${imageSize}`), + uri: avatarUrl || (name === username ? avatar : getResizedAvatar(username, imageSize)), } : DEFAULT_IMAGE; diff --git a/src/utils/image.js b/src/utils/image.js index 009f2d8e6..4730f1b9b 100644 --- a/src/utils/image.js +++ b/src/utils/image.js @@ -64,11 +64,16 @@ export const catchDraftImage = body => { return null; }; -export const getResizedImage = (url, size) => { +export const getResizedImage = (url, size = 400) => { if (!url) return ''; - const _size = size || 400; - if (url.includes('img.esteem')) return `https://img.esteem.ws/${_size}x0/${url}`; + if (url.includes('img.esteem')) return `https://img.esteem.ws/${size}x0/${url}`; return `https://steemitimages.com/${size}x0/${url}`; }; + +export const getResizedAvatar = (author, sizeString = 'small') => { + if (!author) return ''; + + return `https://steemitimages.com/u/${author}/avatar/${sizeString}`; +}; diff --git a/src/utils/postParser.js b/src/utils/postParser.js index bca6cf36a..0a5939ed1 100644 --- a/src/utils/postParser.js +++ b/src/utils/postParser.js @@ -10,6 +10,7 @@ import { getPostReblogs } from '../providers/esteem/esteem'; // Utils import { getReputation } from './reputation'; +import { getResizedImage, getResizedAvatar } from './image'; export const parsePosts = async (posts, currentUserName) => { if (posts) { @@ -33,7 +34,7 @@ export const parsePost = async (post, currentUserName, isPromoted) => { post.image = postImage(post.json_metadata, post.body); post.vote_count = post.active_votes.length; post.author_reputation = getReputation(post.author_reputation); - post.avatar = `https://steemitimages.com/u/${post.author}/avatar/small`; + post.avatar = getResizedAvatar(get(post, 'author')); post.active_votes.sort((a, b) => b.rshares - a.rshares); post.body = renderPostBody(post); @@ -89,7 +90,7 @@ const postImage = (metaData, body) => { } if (imageLink) { - return `https://steemitimages.com/600x0/${imageLink}`; + return getResizedImage(imageLink, 600); } return ''; }; @@ -108,7 +109,7 @@ export const parseComments = async (comments, currentUserName) => { get(comment, 'pending_payout_value') ? get(comment, 'pending_payout_value') : 0, ).toFixed(3); comment.author_reputation = getReputation(get(comment, 'author_reputation')); - comment.avatar = `https://steemitimages.com/u/${get(comment, 'author')}/avatar/small`; + comment.avatar = getResizedAvatar(get(comment, 'author')); comment.markdownBody = get(comment, 'body'); comment.body = renderPostBody(comment); comment.active_votes = activeVotes; @@ -170,7 +171,7 @@ const parseActiveVotes = (post, currentUserName) => { value.reputation = getReputation(get(value, 'reputation')); value.percent /= 100; value.is_down_vote = Math.sign(value.percent) < 0; - value.avatar = `https://steemitimages.com/u/${value.voter}/avatar/small`; + value.avatar = getResizedAvatar(get(value, 'voter')); }); }