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,