diff --git a/react-native/android/app/src/main/res/mipmap-hdpi/service_keybase.png b/react-native/android/app/src/main/res/mipmap-hdpi/service_keybase.png new file mode 100644 index 000000000000..89a265913e91 Binary files /dev/null and b/react-native/android/app/src/main/res/mipmap-hdpi/service_keybase.png differ diff --git a/react-native/android/app/src/main/res/mipmap-mdpi/service_keybase.png b/react-native/android/app/src/main/res/mipmap-mdpi/service_keybase.png new file mode 100644 index 000000000000..484469a6f0c9 Binary files /dev/null and b/react-native/android/app/src/main/res/mipmap-mdpi/service_keybase.png differ diff --git a/react-native/android/app/src/main/res/mipmap-xhdpi/service_keybase.png b/react-native/android/app/src/main/res/mipmap-xhdpi/service_keybase.png new file mode 100644 index 000000000000..6cd22b38c0c0 Binary files /dev/null and b/react-native/android/app/src/main/res/mipmap-xhdpi/service_keybase.png differ diff --git a/react-native/android/app/src/main/res/mipmap-xxhdpi/service_keybase.png b/react-native/android/app/src/main/res/mipmap-xxhdpi/service_keybase.png new file mode 100644 index 000000000000..52142638bc36 Binary files /dev/null and b/react-native/android/app/src/main/res/mipmap-xxhdpi/service_keybase.png differ diff --git a/react-native/android/app/src/main/res/mipmap-xxxhdpi/service_keybase.png b/react-native/android/app/src/main/res/mipmap-xxxhdpi/service_keybase.png new file mode 100644 index 000000000000..a16c275131bc Binary files /dev/null and b/react-native/android/app/src/main/res/mipmap-xxxhdpi/service_keybase.png differ diff --git a/react-native/android/app/src/main/service_keybase-web.png b/react-native/android/app/src/main/service_keybase-web.png new file mode 100644 index 000000000000..9da4a65009df Binary files /dev/null and b/react-native/android/app/src/main/service_keybase-web.png differ diff --git a/react-native/ios/Keybase/Images.xcassets/service_keybase.imageset/Contents.json b/react-native/ios/Keybase/Images.xcassets/service_keybase.imageset/Contents.json new file mode 100644 index 000000000000..7be9c8096d11 --- /dev/null +++ b/react-native/ios/Keybase/Images.xcassets/service_keybase.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "logo.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/react-native/ios/Keybase/Images.xcassets/service_keybase.imageset/logo.png b/react-native/ios/Keybase/Images.xcassets/service_keybase.imageset/logo.png new file mode 100644 index 000000000000..8699bdb30fe1 Binary files /dev/null and b/react-native/ios/Keybase/Images.xcassets/service_keybase.imageset/logo.png differ diff --git a/react-native/react/actions/search.js b/react-native/react/actions/search.js index eafb5b5f6491..7f03af1e5f1d 100644 --- a/react-native/react/actions/search.js +++ b/react-native/react/actions/search.js @@ -1,7 +1,6 @@ 'use strict' import * as SearchActions from '../constants/search-action-types' -import * as ProfileActions from '../constants/profile-action-types' import { routeAppend, getCurrentURI } from './router' import { loadSummaries } from './profile' import engine from '../engine' @@ -18,6 +17,10 @@ export function pushNewSearch () { } } +export function selectService (base, service) { + return { type: SearchActions.SEARCH_SERVICE, base, service } +} + let next_nonce = 0 const submitSearch_debounced = _.debounce((base, term, dispatch, getState) => { diff --git a/react-native/react/constants/images.js b/react-native/react/constants/images.js new file mode 100644 index 000000000000..90df7075a2b4 --- /dev/null +++ b/react-native/react/constants/images.js @@ -0,0 +1,8 @@ +export const services = { + keybase: require('image!service_keybase'), + twitter: require('image!service_twitter'), + github: require('image!service_github'), + reddit: require('image!service_reddit'), + coinbase: require('image!service_coinbase'), + hackernews: require('image!service_hackernews') +} diff --git a/react-native/react/constants/search-action-types.js b/react-native/react/constants/search-action-types.js index 55798d5d309c..b395a21d1dab 100644 --- a/react-native/react/constants/search-action-types.js +++ b/react-native/react/constants/search-action-types.js @@ -3,5 +3,6 @@ export const INIT_SEARCH = 'INIT_SEARCH' export const SEARCH_TERM = 'SEARCH_TERM' +export const SEARCH_SERVICE = 'SEARCH_SERVICE' export const SEARCH_RUNNING = 'SEARCH_RUNNING' export const SEARCH_RESULTS = 'SEARCH_RESULTS' diff --git a/react-native/react/reducers/search.js b/react-native/react/reducers/search.js index 3328ff54952f..630c367356cc 100644 --- a/react-native/react/reducers/search.js +++ b/react-native/react/reducers/search.js @@ -27,6 +27,8 @@ export default function (state: SearchState = initialState, action: any): Search term: '', results: [] }) + case types.SEARCH_SERVICE: + return oldValue.set('service', action.service) case types.SEARCH_TERM: return oldValue.set('term', action.term) case types.SEARCH_RUNNING: diff --git a/react-native/react/search/ScopeBar.js b/react-native/react/search/ScopeBar.js new file mode 100644 index 000000000000..b12d5575c77a --- /dev/null +++ b/react-native/react/search/ScopeBar.js @@ -0,0 +1,74 @@ +'use strict' +/* @flow */ + +import React, { Component, StyleSheet, Image, TouchableHighlight, Text, View } from 'react-native' +import { services as serviceIcons } from '../constants/images' + +const selectedColor = 'rgba(127, 127, 127, 0.2)' + +export default class ScopeBar extends Component { + render () { + return ( + + this.props.onSelectService(null)} + > + + + + + + {['twitter', 'github', 'reddit', 'coinbase', 'hackernews'].map(service => ( + this.props.onSelectService(this.props.selectedService === service ? null : service)} + > + + + ))} + + + ) + } +} + +ScopeBar.propTypes = { + selectedService: React.PropTypes.string, + onSelectService: React.PropTypes.func.isRequired +} + +const styles = StyleSheet.create({ + bar: { + flex: 1, + flexDirection: 'row', + justifyContent: 'flex-end', + height: 45, + paddingHorizontal: 10 + }, + divider: { + justifyContent: 'center' + }, + button: { + width: 36, height: 36, + borderRadius: 18, + marginHorizontal: 2, + marginVertical: 4, + alignItems: 'center', + justifyContent: 'center' + }, + selectedButton: { + backgroundColor: 'rgba(127, 127, 127, 0.4)' + }, + icon: { + width: 24, height: 24, + borderRadius: 12 + }, + keybaseIcon: { + borderRadius: 0, + overflow: 'visible' + } +}) diff --git a/react-native/react/search/index.js b/react-native/react/search/index.js index 137c210b2494..4fc4a5b24c83 100644 --- a/react-native/react/search/index.js +++ b/react-native/react/search/index.js @@ -1,19 +1,13 @@ 'use strict' /* @flow */ -import { submitSearch } from '../actions/search' +import { selectService, submitSearch } from '../actions/search' import { pushNewProfile } from '../actions/profile' import React, { Component, ListView, StyleSheet, TouchableHighlight, Text, TextInput, View, Image } from 'react-native' import commonStyles from '../styles/common' import Immutable from 'immutable' - -const serviceIcons = { - twitter: require('image!service_twitter'), - github: require('image!service_github'), - reddit: require('image!service_reddit'), - coinbase: require('image!service_coinbase'), - hackernews: require('image!service_hackernews') -} +import ScopeBar from './ScopeBar' +import { services as serviceIcons } from '../constants/images' function renderTextWithHighlight (text, highlight, style) { const idx = text.toLowerCase().indexOf(highlight.toLowerCase()) @@ -110,6 +104,13 @@ export default class Search extends Component { + this.props.selectService(this.props.base, service)} + /> + + } renderRow={(...args) => { return this.renderRow(...args) }} keyboardDismissMode='on-drag' pageSize={20} @@ -128,7 +129,8 @@ export default class Search extends Component { }), props: { submitSearch: (base, search) => store.dispatch(submitSearch(base, search)), - pushNewProfile: username => store.dispatch(pushNewProfile(username)) + pushNewProfile: username => store.dispatch(pushNewProfile(username)), + selectService: (base, service) => store.dispatch(selectService(base, service)) } } } @@ -140,6 +142,7 @@ Search.propTypes = { pushNewProfile: React.PropTypes.func.isRequired, base: React.PropTypes.object.isRequired, term: React.PropTypes.string, + service: React.PropTypes.string, results: React.PropTypes.object, error: React.PropTypes.object, waitingForServer: React.PropTypes.bool.isRequired,