Skip to content
This repository has been archived by the owner. It is now read-only.

Lumen search #394

Merged
merged 4 commits into from Jul 19, 2019
Merged
Changes from 1 commit
Commits
File filter
Filter file types
Jump to
Jump to file
Failed to load files.

Always

Just for now

search engine icons and working cliqz integration

  • Loading branch information
chrmod committed Jul 19, 2019
commit 24fd97376602bb35b094dfef114c772e2e819395
@@ -11,13 +11,14 @@
#import <React/RCTViewManager.h>

@interface NativeDrawable : RCTViewManager
@property BOOL hasTint;
@end

@implementation NativeDrawable

RCT_EXPORT_MODULE()

- (UIView *)view
- (UIImageView *)view
{
UIImageView* imageView = [[UIImageView alloc] init];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
@@ -30,6 +31,7 @@ - (UIView *)view
if (color != nil) {
view.image = [view.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[view setTintColor: color];
[self setHasTint:YES];
}
else {
NSLog(@"color %@ is not valid", json);
@@ -41,6 +43,10 @@ - (UIView *)view
NSString *imageName = (NSString*)json;
if (imageName != nil) {
UIImage* image = [UIImage imageNamed:imageName];
if (self.hasTint) {
image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
}

if (image != nil) {
[view setImage:image];
}
@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "bing@1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "bing@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "bing@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "ddg@1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ddg@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ddg@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "google@1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "google@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "google@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -58,14 +58,9 @@ brew install carthage
4. Install Ruby `bundler`:
```sh
sudo gem install bundler
bundle install
```
5. Install [cocoadpods](https://cocoapods.org/) version **1.5.3**
```shell
sudo gem install cocoapods -v 1.5.3
```
6. Fork the repository https://github.com/ghostery/browser-ios from GitHub UI
7. Clone the forked repository + add upstream remote:
5. Fork the repository https://github.com/ghostery/browser-ios from GitHub UI
6. Clone the forked repository + add upstream remote:
```shell
git clone https://github.com/YOUR_USERNAME/ghostery-ios
cd ghostery-ios
@@ -74,18 +69,19 @@ git fetch upstream
git checkout upstream/master
git checkout -b my-working-branch
```
8. Pull in the project dependencies:
7. Pull in the project dependencies:
```shell
sh ./bootstrap.sh
npm ci
npm run bundle-lumen
# Or for Ghostery: npm run bundle-ghostery
npm run bundle-ghostery
# Or for Cliqz: npm run bundle-cliqz
# Or for Lumen: npm run bundle-lumen
rm -rf Pods
bundle install
bundle exec pod install
npm run postinstall
```
9. Open `Client.xcworkspace` in Xcode.
10. Build the `Fennec` scheme in Xcode.
8. Open `Client.xcworkspace` in Xcode.
9. Build the `Ghostery`/`Cliqz`/`Lumen` scheme in Xcode.

Note: When you run `bundle install`, you might get following error `An error occurred while installing unf_ext (0.0.7.5), and Bundler cannot continue.`. Above error happens with ruby 2.5.1. Just make sure to use 2.5.3 ruby version `rvm use 2.5.3` and problem will be fixed.

@@ -1,5 +1,6 @@
import React from 'react';
import { StyleSheet, View, Text, TouchableWithoutFeedback, Animated, Easing, NativeModules } from 'react-native';
import { StyleSheet, View, Text, TouchableWithoutFeedback, Animated, Easing } from 'react-native';
import { XmlEntities } from 'html-entities';

const styles = StyleSheet.create({
container: {
@@ -38,6 +39,15 @@ export default class Onboarding extends React.Component {
isClicked: false,
}

get checkMark() {
if (!this._checkMark) {
const entities = new XmlEntities();
this._checkMark = entities.decode('&#10003;');
}

return this._checkMark;
}

componentWillMount() {
this.animatedValue = new Animated.Value(0);
this.interpolateColor = (from, to) => this.animatedValue.interpolate({
@@ -50,9 +60,8 @@ export default class Onboarding extends React.Component {
});
}

onPress = () => {
NativeModules.Onboarding.tryLumenSearch(true);
this.props.onTryNowPressed();
onPress = (choice) => {
this.props.onChoice(choice);
Animated.timing(this.animatedValue, {
toValue: 150,
duration: 250,
@@ -63,8 +72,8 @@ export default class Onboarding extends React.Component {

render() {
// TODO chrmod: translations
const tryNowText = this.state.isClicked ? 'v' : 'TRY NOW';
const noThanksText = this.state.isClicked ? 'START TYPING' : 'NO, THANKS';
const tryNowText = this.state.isClicked ? this.checkMark : 'TRY NOW';
const noThanksText = this.state.isClicked ? (this.props.hasQuery ? 'SEARCH ACTIVATED' : 'START TYPING') : 'NO, THANKS';
const animatedStyle = {
backgroundColor: this.interpolateColor('#3647D0', '#AEAFFF'),
width: this.interplateWidth,
@@ -86,12 +95,12 @@ export default class Onboarding extends React.Component {
>
This can be changed anytime in settings.
</Animated.Text>
<TouchableWithoutFeedback disabled={this.state.isClicked} onPress={this.onPress}>
<TouchableWithoutFeedback disabled={this.state.isClicked} onPress={() => this.onPress(true)}>
<Animated.View style={[styles.tryNow, animatedStyle]}>
<Text style={{ fontWeight: '700', fontSize: 14, lineHeight: 17, color: 'white' }}>{tryNowText}</Text>
</Animated.View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback disabled={this.state.isClicked}>
<TouchableWithoutFeedback disabled={this.state.isClicked} onPress={() => this.onPress(false)}>
<>
<Animated.Text style={{ letterSpacing: -0.2, marginTop: 20, fontSize: 14, lineHeight: 17, fontWeight: '700', color: this.interpolateColor('#3647D0', '#3647D0')}}>{noThanksText}</Animated.Text>
</>
@@ -2,7 +2,7 @@ import 'react-native/Libraries/Core/InitializeCore';
import './setup';
import 'process-nextick-args';
import React from 'react';
import { AppRegistry, StyleSheet, View, Text, ScrollView, NativeModules, Image, NativeEventEmitter } from 'react-native';
import { AppRegistry, StyleSheet, View, Text, ScrollView, NativeModules, NativeEventEmitter, TouchableWithoutFeedback } from 'react-native';
import { startup } from 'browser-core-lumen-ios';
import Cliqz from './cliqzWrapper';
import { setDefaultSearchEngine } from 'browser-core-lumen-ios/build/modules/core/search-engines';
@@ -14,6 +14,8 @@ import SearchUIVertical from 'browser-core-lumen-ios/build/modules/mobile-cards-
import { Provider as CliqzProvider } from 'browser-core-lumen-ios/build/modules/mobile-cards/cliqz';
import { Provider as ThemeProvider } from 'browser-core-lumen-ios/build/modules/mobile-cards-vertical/withTheme';
import Onboarding from './lumen-onboarding';
import inject from 'browser-core-lumen-ios/build/modules/core/kord/inject';
import NativeDrawable, { normalizeUrl } from 'browser-core-lumen-ios/build/modules/mobile-cards/components/custom/NativeDrawable';

const nativeBridge = NativeModules.JSBridge;

@@ -36,7 +38,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
borderBottomLeftRadius: 5,
borderBottomRightRadius: 5
borderBottomRightRadius: 5
},
searchEnginesContainer: {
flexDirection: 'row',
@@ -45,8 +47,8 @@ const styles = StyleSheet.create({
marginBottom: 100,
},
searchEngineIcon: {
height: 20,
width: 20,
height: 73,
width: 73,
borderRadius: 10,
overflow: 'hidden',
},
@@ -61,6 +63,7 @@ class MobileCards extends React.Component {
results: [],
meta: {}
},
hasQuery: false,
theme: 'lumen-light'
}

@@ -84,18 +87,20 @@ class MobileCards extends React.Component {
this.eventEmitter.removeAllListeners();
}

onAction = ({ action, args, id }) => {
onAction = async ({ action, args, id }) => {
const [module, name] = action.split(':');
// TODO chrmod: it breaks in `inject.es` when you type clear and type again
// TODO chrmod: block messages
return this.appStart.then((app) => {
return app.modules[module].action(name, ...args).then((response) => {
if (typeof id !== 'undefined') {
nativeBridge.replyToAction(id, response);
}
return response;
if (this.state.onboarding === true && module === 'search' && name === 'startSearch') {
// don't start search until onboarding is finished
this.retryLastSearch = () => this.onAction({ action, args, id });
this.setState({
hasQuery: true,
});
}).catch(e => console.error(e));
return;
}
const response = await inject.module(module).action(name, ...args);
if (typeof id !== 'undefined') {
nativeBridge.replyToAction(id, response);
}
}

setSearchEngine = (engine) => {
@@ -113,8 +118,22 @@ class MobileCards extends React.Component {

updateResults = results => this.setState({ results, onboarding: false });

onTryNowPressed = () => {
// TODO chrmod: let messages pass
onTryNowPressed = (choice) => {
NativeModules.Onboarding.tryLumenSearch(choice);
setTimeout(() => {
this.setState({
onboarding: false,
}, () => {
if (choice && this.retryLastSearch) {
this.retryLastSearch();
this.retryLastSearch = null;
}
});
}, 1000); // wait for onboarding animation to finish
}

openLink = (url) => {
NativeModules.BrowserActions.openLink(url, this.state.results.query, true);
}

render() {
@@ -124,7 +143,7 @@ class MobileCards extends React.Component {
const SearchComponent = layout === "horizontal" ? SearchUI : SearchUIVertical;
if (this.state.onboarding) {
return (
<Onboarding onTryNowPressed={this.onTryNowPressed} />
<Onboarding onChoice={this.onTryNowPressed} hasQuery={this.state.hasQuery}/>
);
} else {
NativeModules.QuerySuggestion.showQuerySuggestions(query, suggestions);
@@ -137,7 +156,7 @@ class MobileCards extends React.Component {
results={results}
meta={meta}
theme={appearance}
style={{ backgroundColor: 'transparent', }}
style={{ backgroundColor: 'white', paddingTop: 9 }}
cardListStyle={{ paddingLeft: 0, paddingRight: 0 }}
header={<View />}
separator={<View style={{ height: 0.5, backgroundColor: '#D9D9D9' }} />}
@@ -160,18 +179,30 @@ class MobileCards extends React.Component {
</View>
<View style={styles.searchEnginesContainer}>
{ /* TODO chrmod: list + send openlink event onclick + real pngs */ }
<Image
style={styles.searchEngineIcon}
source={{ uri: 'https://cdn4.iconfinder.com/data/icons/new-google-logo-2015/400/new-google-favicon-512.png' }}
/>
<Image
style={styles.searchEngineIcon}
source={{ uri: 'https://duckduckgo.com/assets/icons/meta/DDG-icon_256x256.png' }}
/>
<Image
style={styles.searchEngineIcon}
source={{ uri: 'https://www.sclance.com/pngs/bing-png/bing_png_121500.png' }}
/>
<TouchableWithoutFeedback
onPress={() => this.openLink(`https://google.com/search?q=${encodeURIComponent(this.state.results.query)}`)}
>
<NativeDrawable
style={styles.searchEngineIcon}
source={normalizeUrl('google.svg')}
/>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={() => this.openLink(`https://duckduckgo.com/?q=${encodeURIComponent(this.state.results.query)}`)}
>
<NativeDrawable
style={styles.searchEngineIcon}
source={normalizeUrl('ddg.svg')}
/>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={() => this.openLink(`https://www.bing.com/search?q=${encodeURIComponent(this.state.results.query)}`)}
>
<NativeDrawable
style={styles.searchEngineIcon}
source={normalizeUrl('bing.svg')}
/>
</TouchableWithoutFeedback>
</View>
</>
</ScrollView>
ProTip! Use n and p to navigate between commits in a pull request.