mirror of
https://github.com/ecency/ecency-mobile.git
synced 2025-01-03 11:34:30 +03:00
commit
b5d75d16b6
@ -1,3 +1,3 @@
|
||||
BACKEND_URL = https://myapi.com
|
||||
SEARCH_API_URL = https://search.com
|
||||
SEARCH_API_TOKEN = abcde
|
||||
BACKEND_URL=https://myapi.com
|
||||
SEARCH_API_URL=https://search.com
|
||||
SEARCH_API_TOKEN=abcde
|
@ -1,4 +1,5 @@
|
||||
apply plugin: "com.android.application"
|
||||
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
|
||||
|
||||
import com.android.build.OutputFile
|
||||
|
||||
|
@ -199,13 +199,6 @@
|
||||
remoteGlobalIDString = EB2648DF1C7BE17A00B8F155;
|
||||
remoteInfo = ReactNativeConfig;
|
||||
};
|
||||
0CA1AD3C21A818CF001EAFBD /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = C1AC2A99CB0143E580183824 /* RNViewOverflow.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RNViewOverflow;
|
||||
};
|
||||
139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
|
||||
@ -402,7 +395,7 @@
|
||||
remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4;
|
||||
remoteInfo = "jschelpers-tvOS";
|
||||
};
|
||||
47241C6321A85341001094B9 /* PBXContainerItemProxy */ = {
|
||||
58C9351B21AB3BA000D2EB1F /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = C1AC2A99CB0143E580183824 /* RNViewOverflow.xcodeproj */;
|
||||
proxyType = 2;
|
||||
@ -757,7 +750,7 @@
|
||||
0CE2BA1E21A7301B0052071F /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0CE2BA2221A7301B0052071F /* libRNViewOverflow.a */,
|
||||
58C9351C21AB3BA000D2EB1F /* libRNViewOverflow.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -1084,7 +1077,7 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "eSteem" */;
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "esteem" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
@ -1309,13 +1302,6 @@
|
||||
remoteRef = 0C09B6DB21A3393A00536C9D /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
0CE2BA2221A7301B0052071F /* libRNViewOverflow.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRNViewOverflow.a;
|
||||
remoteRef = 0CE2BA2121A7301B0052071F /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
@ -1505,11 +1491,11 @@
|
||||
remoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
47241C6421A85341001094B9 /* libRNViewOverflow.a */ = {
|
||||
58C9351C21AB3BA000D2EB1F /* libRNViewOverflow.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRNViewOverflow.a;
|
||||
remoteRef = 47241C6321A85341001094B9 /* PBXContainerItemProxy */;
|
||||
remoteRef = 58C9351B21AB3BA000D2EB1F /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
|
||||
@ -2195,6 +2181,9 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_OTHER_PREPROCESSOR_FLAGS = "-traditional";
|
||||
INFOPLIST_PREFIX_HEADER = "${BUILD_DIR}/GeneratedInfoPlistDotEnv.h";
|
||||
INFOPLIST_PREPROCESS = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
@ -2241,6 +2230,9 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_OTHER_PREPROCESSOR_FLAGS = "-traditional";
|
||||
INFOPLIST_PREFIX_HEADER = "${BUILD_DIR}/GeneratedInfoPlistDotEnv.h";
|
||||
INFOPLIST_PREPROCESS = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
@ -2287,7 +2279,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "eSteem" */ = {
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "esteem" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
} from 'react-native';
|
||||
import FastImage from 'react-native-fast-image';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import { SearchModal } from '../../searchModal';
|
||||
|
||||
// Utils
|
||||
import { getReputation } from '../../../utils/user';
|
||||
@ -25,7 +26,9 @@ class HeaderView extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
this.state = {
|
||||
isSearchModalOpen: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Component Life Cycles
|
||||
@ -52,6 +55,10 @@ class HeaderView extends Component {
|
||||
return DEFAULT_IMAGE;
|
||||
};
|
||||
|
||||
_handleOnCloseSearch = () => {
|
||||
this.setState({ isSearchModalOpen: false });
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
handleOpenDrawer,
|
||||
@ -60,12 +67,14 @@ class HeaderView extends Component {
|
||||
isReverse,
|
||||
currentAccount,
|
||||
} = this.props;
|
||||
const { isSearchModalOpen } = this.state;
|
||||
const _name = this._getNameOfUser();
|
||||
const _reputation = getReputation(currentAccount.reputation);
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.container, isReverse && styles.containerReverse]}>
|
||||
<StatusBar hidden={hideStatusBar} translucent />
|
||||
<SearchModal isOpen={isSearchModalOpen} handleOnClose={this._handleOnCloseSearch} />
|
||||
<TouchableOpacity
|
||||
style={styles.avatarWrapper}
|
||||
onPress={() => !isReverse && handleOpenDrawer()}
|
||||
@ -112,6 +121,24 @@ class HeaderView extends Component {
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{!isReverse && (
|
||||
<View
|
||||
style={{
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'center',
|
||||
flex: 1,
|
||||
marginRight: 16,
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
style={styles.searchButton}
|
||||
iconStyle={styles.backIcon}
|
||||
name="md-search"
|
||||
onPress={() => this.setState({ isSearchModalOpen: true })}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ export default class Modal extends Component {
|
||||
|
||||
render() {
|
||||
const {
|
||||
isFullScreen, isOpen, children, isRadius,
|
||||
isFullScreen, isOpen, children, isRadius, isTransparent,
|
||||
} = this.props;
|
||||
return (
|
||||
<ModalBox
|
||||
@ -40,6 +40,7 @@ export default class Modal extends Component {
|
||||
isRadius && styles.borderTopRadius,
|
||||
isFullScreen ? styles.fullModal : styles.centerModal,
|
||||
]}
|
||||
transparent={isTransparent}
|
||||
animationType="fade"
|
||||
visible={isOpen}
|
||||
onRequestClose={() => this._handleOnClose(this)}
|
||||
|
96
src/components/searchModal/container/searchModalContainer.js
Normal file
96
src/components/searchModal/container/searchModalContainer.js
Normal file
@ -0,0 +1,96 @@
|
||||
import React, { Component } from 'react';
|
||||
import { withNavigation } from 'react-navigation';
|
||||
|
||||
// Services and Actions
|
||||
import { search } from '../../../providers/esteem/esteem';
|
||||
import { lookupAccounts } from '../../../providers/steem/dsteem';
|
||||
|
||||
// Middleware
|
||||
|
||||
// Constants
|
||||
import { default as ROUTES } from '../../../constants/routeNames';
|
||||
|
||||
// Utilities
|
||||
|
||||
// Component
|
||||
import { SearchModalView } from '..';
|
||||
|
||||
/*
|
||||
* Props Name Description Value
|
||||
*@props --> props name here description here Value Type Here
|
||||
*
|
||||
*/
|
||||
|
||||
class SearchModalContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
searchResults: {},
|
||||
};
|
||||
}
|
||||
|
||||
// Component Life Cycle Functions
|
||||
|
||||
// Component Functions
|
||||
_handleCloseButton = () => {
|
||||
const { navigation } = this.props;
|
||||
navigation.goBack();
|
||||
};
|
||||
|
||||
_handleOnChangeSearchInput = (text) => {
|
||||
if (text && text !== '@') {
|
||||
if (text[0] === '@') {
|
||||
lookupAccounts(text.substr(1)).then((res) => {
|
||||
const users = res.map(item => ({ author: item }));
|
||||
this.setState({ searchResults: { type: 'user', data: users } });
|
||||
});
|
||||
} else {
|
||||
search({ q: text }).then((res) => {
|
||||
res.results = res.results.filter(item => item.title !== '');
|
||||
this.setState({ searchResults: { type: 'content', data: res.results } });
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_handleOnPressListItem = (type, item) => {
|
||||
const { navigation, handleOnClose } = this.props;
|
||||
handleOnClose();
|
||||
this.setState({ searchResults: {} });
|
||||
if (type === 'user') {
|
||||
navigation.navigate({
|
||||
routeName: ROUTES.SCREENS.PROFILE,
|
||||
params: {
|
||||
username: item.author,
|
||||
},
|
||||
key: item.author,
|
||||
});
|
||||
} else if (type === 'content') {
|
||||
navigation.navigate({
|
||||
routeName: ROUTES.SCREENS.POST,
|
||||
params: {
|
||||
author: item.author,
|
||||
permlink: item.permlink,
|
||||
},
|
||||
key: item.permlink,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { searchResults } = this.state;
|
||||
const { handleOnClose, isOpen } = this.props;
|
||||
return (
|
||||
<SearchModalView
|
||||
searchResults={searchResults}
|
||||
handleCloseButton={this._handleCloseButton}
|
||||
handleOnChangeSearchInput={this._handleOnChangeSearchInput}
|
||||
handleOnPressListItem={this._handleOnPressListItem}
|
||||
isOpen={isOpen}
|
||||
handleOnClose={handleOnClose}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withNavigation(SearchModalContainer);
|
5
src/components/searchModal/index.js
Normal file
5
src/components/searchModal/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
import SearchModalView from './view/searchModalView';
|
||||
import SearchModal from './container/searchModalContainer';
|
||||
|
||||
export { SearchModalView, SearchModal };
|
||||
export default SearchModal;
|
64
src/components/searchModal/view/searchModalStyles.js
Normal file
64
src/components/searchModal/view/searchModalStyles.js
Normal file
@ -0,0 +1,64 @@
|
||||
import EStyleSheet from 'react-native-extended-stylesheet';
|
||||
|
||||
export default EStyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: 'rgba(0,0,0,0.8)',
|
||||
},
|
||||
inputWrapper: {
|
||||
backgroundColor: '$primaryLightBackground',
|
||||
flexDirection: 'row',
|
||||
height: 44,
|
||||
margin: 16,
|
||||
borderRadius: 8,
|
||||
marginTop: 20,
|
||||
padding: 5,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
icon: {
|
||||
alignSelf: 'center',
|
||||
color: '$primaryDarkGray',
|
||||
marginLeft: 16,
|
||||
},
|
||||
input: {
|
||||
color: '$primaryDarkGray',
|
||||
fontSize: 14,
|
||||
flexGrow: 1,
|
||||
paddingHorizontal: 10,
|
||||
},
|
||||
closeIconButton: {
|
||||
backgroundColor: '$iconColor',
|
||||
width: 20,
|
||||
height: 20,
|
||||
borderRadius: 20 / 2,
|
||||
justifyContent: 'center',
|
||||
alignSelf: 'center',
|
||||
marginRight: 16,
|
||||
},
|
||||
closeIcon: {
|
||||
color: '$white',
|
||||
fontSize: 16,
|
||||
},
|
||||
body: {
|
||||
marginTop: 16,
|
||||
marginRight: 24,
|
||||
},
|
||||
searhItems: {
|
||||
marginHorizontal: 30,
|
||||
marginVertical: 10,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
searchItemImage: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
borderWidth: 1,
|
||||
borderColor: '$primaryGray',
|
||||
},
|
||||
searchItemText: {
|
||||
color: '$white',
|
||||
marginLeft: 10,
|
||||
},
|
||||
});
|
99
src/components/searchModal/view/searchModalView.js
Normal file
99
src/components/searchModal/view/searchModalView.js
Normal file
@ -0,0 +1,99 @@
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import {
|
||||
View, Text, TextInput, FlatList, TouchableHighlight, Image,
|
||||
} from 'react-native';
|
||||
|
||||
// Constants
|
||||
|
||||
// Components
|
||||
import { Icon } from '../../icon';
|
||||
import { IconButton } from '../../iconButton';
|
||||
import { Modal } from '../..';
|
||||
|
||||
// Styles
|
||||
// eslint-disable-next-line
|
||||
import styles from './searchModalStyles';
|
||||
|
||||
class SearchModalView extends Component {
|
||||
/* Props
|
||||
* ------------------------------------------------
|
||||
* @prop { type } name - Description....
|
||||
*/
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
// Component Life Cycles
|
||||
|
||||
// Component Functions
|
||||
|
||||
render() {
|
||||
const {
|
||||
isOpen,
|
||||
handleOnClose,
|
||||
searchResults,
|
||||
handleOnPressListItem,
|
||||
handleOnChangeSearchInput,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Modal isOpen={isOpen} isFullScreen swipeToClose backButtonClose isTransparent>
|
||||
<View style={styles.container}>
|
||||
<View style={styles.inputWrapper}>
|
||||
<Icon style={styles.icon} iconType="FontAwesome" name="search" size={20} />
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
onChangeText={text => handleOnChangeSearchInput(text)}
|
||||
placeholder="Search..."
|
||||
placeholderTextColor="#c1c5c7"
|
||||
/>
|
||||
<IconButton
|
||||
iconStyle={styles.closeIcon}
|
||||
iconType="FontAwesome"
|
||||
style={styles.closeIconButton}
|
||||
name="close"
|
||||
onPress={() => handleOnClose()}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.body}>
|
||||
<FlatList
|
||||
data={searchResults.data}
|
||||
showsVerticalScrollIndicator={false}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableHighlight
|
||||
onPress={() => handleOnPressListItem(searchResults.type, item)}
|
||||
>
|
||||
<View style={styles.searhItems}>
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
searchResults.type === 'user'
|
||||
? `https://steemitimages.com/u/${item.author}/avatar/small`
|
||||
: item.img_url
|
||||
|| `https://steemitimages.com/u/${item.author}/avatar/small`,
|
||||
}}
|
||||
style={styles.searchItemImage}
|
||||
/>
|
||||
<Text style={styles.searchItemText}>
|
||||
{searchResults.type === 'user' ? item.author : item.title}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
)}
|
||||
keyExtractor={(post, index) => index.toString()}
|
||||
removeClippedSubviews
|
||||
onEndThreshold={0}
|
||||
initialNumToRender={20}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SearchModalView;
|
@ -4,7 +4,7 @@ import Config from 'react-native-config';
|
||||
const search = axios.create({
|
||||
baseURL: Config.SEARCH_API_URL,
|
||||
headers: {
|
||||
'Authorization': Config.SEARCH_API_TOKEN,
|
||||
Authorization: Config.SEARCH_API_TOKEN,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
import api from '../../config/api';
|
||||
import searchApi from '../../config/search';
|
||||
|
||||
export const getDrafts = data => new Promise((resolve, reject) => {
|
||||
api
|
||||
@ -93,3 +94,14 @@ export const getUnreadActivityCount = data => new Promise((resolve, reject) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
export const search = data => new Promise((resolve, reject) => {
|
||||
searchApi
|
||||
.post('/search', data)
|
||||
.then((res) => {
|
||||
resolve(res.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
|
@ -34,6 +34,7 @@ export default class HomeScreen extends PureComponent {
|
||||
return (
|
||||
<Fragment>
|
||||
<Header />
|
||||
|
||||
<View style={styles.container} key="overlay">
|
||||
<ScrollableTabView
|
||||
style={styles.tabView}
|
||||
|
Loading…
Reference in New Issue
Block a user