From bf8302827c5f207533c4961852824df55c8a0e6e Mon Sep 17 00:00:00 2001 From: Krzysztof Jan Modras Date: Fri, 19 Jul 2019 15:08:40 +0200 Subject: [PATCH] Lumen search (#394) * Implement Search with onboarding on lumen * adding missing file * search engine icons and working cliqz integration * translations --- Client.xcodeproj/project.pbxproj | 8 + Cliqz/React Components/Engine.swift | 2 +- Cliqz/React Components/Modules/JSBridge.swift | 5 +- .../React Components/Modules/NativeDrawable.m | 8 +- .../React Components/Modules/Onboarding.swift | 27 +++ .../Modules/OnboardingBridge.m | 15 ++ .../ic_ez_bing.imageset/Contents.json | 23 +++ .../ic_ez_bing.imageset/bing@1x.png | Bin 0 -> 814 bytes .../ic_ez_bing.imageset/bing@2x.png | Bin 0 -> 2004 bytes .../ic_ez_bing.imageset/bing@3x.png | Bin 0 -> 5563 bytes .../ic_ez_ddg.imageset/Contents.json | 23 +++ .../ReactCards/ic_ez_ddg.imageset/ddg@1x.png | Bin 0 -> 1030 bytes .../ReactCards/ic_ez_ddg.imageset/ddg@2x.png | Bin 0 -> 2625 bytes .../ReactCards/ic_ez_ddg.imageset/ddg@3x.png | Bin 0 -> 7751 bytes .../ic_ez_google.imageset/Contents.json | 23 +++ .../ic_ez_google.imageset/google@1x.png | Bin 0 -> 861 bytes .../ic_ez_google.imageset/google@2x.png | Bin 0 -> 2082 bytes .../ic_ez_google.imageset/google@3x.png | Bin 0 -> 5937 bytes README.md | 22 +-- js/i18n.js | 25 +++ js/localization/de.json | 35 ++++ js/localization/en.json | 35 ++++ js/lumen-onboarding.js | 112 +++++++++++ lumen.js | 182 ++++++++++++++---- package-lock.json | 55 ++++-- package.json | 3 +- 26 files changed, 529 insertions(+), 74 deletions(-) create mode 100644 Cliqz/React Components/Modules/Onboarding.swift create mode 100644 Cliqz/React Components/Modules/OnboardingBridge.m create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/Contents.json create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@1x.png create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@2x.png create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@3x.png create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_ddg.imageset/Contents.json create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_ddg.imageset/ddg@1x.png create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_ddg.imageset/ddg@2x.png create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_ddg.imageset/ddg@3x.png create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/Contents.json create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@1x.png create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@2x.png create mode 100644 Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@3x.png create mode 100644 js/i18n.js create mode 100644 js/localization/de.json create mode 100644 js/localization/en.json create mode 100644 js/lumen-onboarding.js diff --git a/Client.xcodeproj/project.pbxproj b/Client.xcodeproj/project.pbxproj index 38877fc07..89ec5c24d 100644 --- a/Client.xcodeproj/project.pbxproj +++ b/Client.xcodeproj/project.pbxproj @@ -212,6 +212,8 @@ 28F596A11ACA13CA0071DDCC /* InfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28F596A01ACA13CA0071DDCC /* InfoTests.swift */; }; 28F657EA1ABFCA7A00A608BD /* LiveAccountTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FA4363B1ABB8448008031D1 /* LiveAccountTest.swift */; }; 28FDFF0C1C1F725800840F86 /* SeparatorTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FDFF0B1C1F725800840F86 /* SeparatorTableCell.swift */; }; + 2979623922DF695E00604955 /* Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2979623822DF695E00604955 /* Onboarding.swift */; }; + 2979624322DF697900604955 /* OnboardingBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 2979624222DF697900604955 /* OnboardingBridge.m */; }; 2C28F96C201B2D4C00ABA8A5 /* MailAppSettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C28F96B201B2D4C00ABA8A5 /* MailAppSettingsTests.swift */; }; 2C2A5EF41E68469500F02659 /* PrivateBrowsingTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2A5EF31E68469500F02659 /* PrivateBrowsingTest.swift */; }; 2C2A91291FA2410D002E36BD /* HistoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2A91281FA2410D002E36BD /* HistoryTests.swift */; }; @@ -1668,6 +1670,8 @@ 28ED02281B262E0A003948B2 /* IndependentRecordSynchronizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IndependentRecordSynchronizer.swift; path = Synchronizers/IndependentRecordSynchronizer.swift; sourceTree = ""; }; 28F596A01ACA13CA0071DDCC /* InfoTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = InfoTests.swift; path = SyncTests/InfoTests.swift; sourceTree = ""; }; 28FDFF0B1C1F725800840F86 /* SeparatorTableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SeparatorTableCell.swift; sourceTree = ""; }; + 2979623822DF695E00604955 /* Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Onboarding.swift; sourceTree = ""; }; + 2979624222DF697900604955 /* OnboardingBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OnboardingBridge.m; sourceTree = ""; }; 2C28F96B201B2D4C00ABA8A5 /* MailAppSettingsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailAppSettingsTests.swift; sourceTree = ""; }; 2C2A5EF31E68469500F02659 /* PrivateBrowsingTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrivateBrowsingTest.swift; sourceTree = ""; }; 2C2A91281FA2410D002E36BD /* HistoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryTests.swift; sourceTree = ""; }; @@ -3518,6 +3522,8 @@ children = ( 4F30F4F42051670C0049E4F6 /* AutoCompletion.swift */, 4F30F4F52051670C0049E4F6 /* AutoCompletionBridge.m */, + 2979623822DF695E00604955 /* Onboarding.swift */, + 2979624222DF697900604955 /* OnboardingBridge.m */, 4F30F4F62051670C0049E4F6 /* BrowserActions.swift */, 4F30F4F72051670C0049E4F6 /* BrowserActionsBridge.m */, 4F30F4F82051670C0049E4F6 /* Crypto.swift */, @@ -6935,6 +6941,7 @@ E68AEDB01B18F81A00133D99 /* SwipeAnimator.swift in Sources */, AFA1DE0C2088BE0500B27B8A /* BlockListFileManager.swift in Sources */, 1E23E61D22258D0B0004FAAF /* LegacyTelemetryHelper.swift in Sources */, + 2979624322DF697900604955 /* OnboardingBridge.m in Sources */, 4F30F50A2051670C0049E4F6 /* BrowserActions.swift in Sources */, 1E2C435C21F89E8100891FB2 /* LumenDarkTheme.swift in Sources */, 3BF56D271CDBBE1F00AC4D75 /* SimpleToast.swift in Sources */, @@ -7046,6 +7053,7 @@ 4FE43F5B221EE96D00045527 /* WelcomeView.swift in Sources */, 1E3CBC152057D83700898B05 /* CliqzAppSettingsTableViewController.swift in Sources */, D04CD718215EBD85004FF5B0 /* SettingsLoadingView.swift in Sources */, + 2979623922DF695E00604955 /* Onboarding.swift in Sources */, D04CD74C216CF86B004FF5B0 /* InstructionsViewController.swift in Sources */, E49943F51AE6879C00BF9DE4 /* IntroViewController.swift in Sources */, ); diff --git a/Cliqz/React Components/Engine.swift b/Cliqz/React Components/Engine.swift index 6e7ed7d8d..adafc79da 100644 --- a/Cliqz/React Components/Engine.swift +++ b/Cliqz/React Components/Engine.swift @@ -31,7 +31,7 @@ open class Engine { let jsCodeLocation = Bundle.main.url(forResource: "jsengine.bundle", withExtension: "js") #endif - rootView = RCTRootView( bundleURL: jsCodeLocation, moduleName: "ExtensionApp", initialProperties: nil, launchOptions: nil ) + rootView = RCTRootView( bundleURL: jsCodeLocation, moduleName: "ExtensionApp", initialProperties: ["showSearchOnboarding": true], launchOptions: nil ) bridge = rootView.bridge //ConnectManager.sharedInstance.refresh() } diff --git a/Cliqz/React Components/Modules/JSBridge.swift b/Cliqz/React Components/Modules/JSBridge.swift index cb9580f8b..76defbe0a 100644 --- a/Cliqz/React Components/Modules/JSBridge.swift +++ b/Cliqz/React Components/Modules/JSBridge.swift @@ -59,7 +59,8 @@ class JSBridge : RCTEventEmitter { } override open func supportedEvents() -> [String]! { - return ["callAction", "publishEvent"] + // TODO chrmod: clean native bridge + return ["action", "callAction", "publishEvent"] } override open func constantsToExport() -> [AnyHashable : Any]! { @@ -118,7 +119,7 @@ class JSBridge : RCTEventEmitter { self.eventCallbacks[actionId] = callback } // only send event - callback is handled in action reply - self.sendEvent(withName: "callAction", body: ["id": actionId, "action": functionName, "args": args]) + self.sendEvent(withName: "action", body: ["id": actionId, "action": functionName, "args": args]) } diff --git a/Cliqz/React Components/Modules/NativeDrawable.m b/Cliqz/React Components/Modules/NativeDrawable.m index 04e5609ba..3a710f8a5 100644 --- a/Cliqz/React Components/Modules/NativeDrawable.m +++ b/Cliqz/React Components/Modules/NativeDrawable.m @@ -11,13 +11,14 @@ #import @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]; } diff --git a/Cliqz/React Components/Modules/Onboarding.swift b/Cliqz/React Components/Modules/Onboarding.swift new file mode 100644 index 000000000..6f4c0be88 --- /dev/null +++ b/Cliqz/React Components/Modules/Onboarding.swift @@ -0,0 +1,27 @@ +// +// Onboarding.swift +// Client +// +// Created by Khaled Tantawy on 17.07.19. +// Copyright © 2019 Cliqz. All rights reserved. +// + +import React + +@objc(Onboarding) +class Onboarding: RCTEventEmitter { + + override static func requiresMainQueueSetup() -> Bool { + return false + } + + @objc(tryLumenSearch:) + func tryLumenSearch(accepted: Bool) { + debugPrint("tryLumenSearch -- \(accepted)") + if accepted { + // TODO: PK this is try now case. Change Lumen to default search engine. UI will be handled by extenstion + } else { + // TODO: PK close cliqz search and open queary with default search engine + } + } +} diff --git a/Cliqz/React Components/Modules/OnboardingBridge.m b/Cliqz/React Components/Modules/OnboardingBridge.m new file mode 100644 index 000000000..d62c2d717 --- /dev/null +++ b/Cliqz/React Components/Modules/OnboardingBridge.m @@ -0,0 +1,15 @@ +// +// OnboardingBridge.m +// Client +// +// Created by Khaled Tantawy on 17.07.19. +// Copyright © 2019 Cliqz. All rights reserved. +// + +#import +#import +@interface RCT_EXTERN_MODULE(Onboarding, NSObject) +RCT_EXTERN_METHOD(tryLumenSearch:(BOOL) accepted) +@end + + diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/Contents.json b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/Contents.json new file mode 100644 index 000000000..23f6a32e3 --- /dev/null +++ b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/Contents.json @@ -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" + } +} \ No newline at end of file diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@1x.png b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..9d89ebe7e1eb1c4801dcc4cc11d7cc9fc8a0c9fc GIT binary patch literal 814 zcmV+}1JV46P)F|7{K4oMfBv^izm?z`n@Hri$sS)1%o<>P!|yr3O1Ih(Jli^urx`VAuP>WorX;q zY%4?%3GJ|N+fSrJL>CWsjUf7mu%f$N=D~BFnfG>F!#?=2Z@&57_x<=_hmij`Vn^V_ zh%{ZU*)ox(R2ypnG*wDT;^She=TiZ}kIyezX9IGPWwZ|q#ST7n!(}uGQ7)BA$;2WF zX;?r&iHILqK-he}*&9X5x7c;vR&)?pp3$hFgMbb~BU1h{kKEQZ2VphOXfs#~my!x; zOAf;FJfo`~;@J<``!xq)ML{Z1#+_%>^#&~qXSWV9_exT`!_`R(AKlh#UH|v->XWu4y4mJt%fdh4ctQVpOZO z9hJMfg)ljpYm@%%Z$D(6x`mKTGb-cT_no{b<1TLxsoYC?LQ3BuLWq_y5w52gRpIXA zjsBm%DsNQlISI1?p@{~BqA+11jHi6RLB2vULQ>k8i7;v~devZbG=TbdsnKDx)G5^M+_Nx!xX6AaMF_6uVDf s%C+(L3Vj+1S+k=ODNdBkafnIdFE3Oi8u^bYasU7T07*qoM6N<$f@x)U0ssI2 literal 0 HcmV?d00001 diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@2x.png b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..760d9acdeb0d1f4e0d3954f9302a4bb1951416dc GIT binary patch literal 2004 zcmV;_2P^oAP)An-h6j$}AvjVLjI@edpRASMK|hG@n}v+*X?bFo?n zb6V4_T|ktwNsd^T6bTdK0^PIq*$9d+(V6fvwg8d0O&Pjuz4H(I)Z2Mo@8!AnYJ8G! zwmx^g-}8L-+;!`&0OY0>n8<&!nF0Av!({^|Z_#p%V{5EjW7rxi*ORwBR<0*(YbdKH z!6lQoP^=-0#MW5MV4P0pv}h<={C)eWx#!!vm-a^poGQN@i!F#Bj?WCaTtyau*#d|I z0B{b6qwq{y=d2$h1e(n^pLfm|cwst2tegRH002(lh3Vf%dKOJJ>0SY&bjbvE?oh`J z23T1K;s5|#$mJ^fu|2+6FN&6^9Wxq=7MsM%8WINp;Ldz@dNzp=D34hfwJ2-Eh4^Bp z(>X1hP`ZJ5o-gbcx|dpwlL@QC+$m@skRS;6k|PAt;8u*VfDvw$MaYn;_Eq+)>?g0^ z^=a1}gHVN|9Umi@RMV5nU`jttykI8;I zzGF?X`&q3fO+WwuuKi&5(rB2#Xqdn+S}?L}=oq760v!&%&@7bZRdgbJdUielDWQ%X z>RSTzU7w7tBA3fm6bTa;2@@!^V3aSRV~#X;JZNS$X+mm09ABJ|NOCBnt4ZUeBOSrw{2!pl8vMAc04M1hxh+%EyF*1crmUR+DBV&f#zr(gL}j zC<~;vQ0FYYt0^N=XkX_nTA(F>5sUoz-IWa=g-$PLbv&&J2MPSRrS~!BNEC=Ak|>I! zk|d3fj*gw^iCtK?zxh;2wvddRa#I31oz7{&Ac4Ukfq?)*LPB$P`G_Ulq+q=p6p8yX0#ug8dG{*82NSF(Rt6vc_LvGH&E`>$0tH}|bz zU7OB{8IrGoKwkra-g=B!Mu~L!@~z$8dW;4JZ@(@n+Qfu-ap=nJx=-4^D`!!g&dKEp z71p&1v=lt_bvzw@B8V{T;H&dI=iP@_gJs@i+CDNs#k-DKP zcixsHX*?Z{BuR;jgClR6t<4;1=R2_lZXbbei;+Z85~skC?%o|Ib?^6n=HtufAj@P9={Kox|q0@IxAbG$R!N061E} zDyVFPj$iL8(u`EIw_^q^vXRFq-;(+v@9BC}?pcXn_Yml;#VB7w$Gn~=kLUn0gj4_k;5P8_#rXzB#|uo} zRib${Ii1dFsh><9K+$oo+Hpq9dq+%=3IG7yb2S|^)_Mq}d9fBFJ0>;8J?!qC)cWKC z008&G_O3Z=-2~F)8suL<$#Jcz(S7q)S|CGEYj(yK$f2IC#mEk!<9VS**KgL=AOQfl zwOiv0>7Z8I0Lp40!%(ZLPtIGNL|W}8&{2y~E<)=+XY3Ty3}hH;&Cb~UPrC`Ma1;1+ zGLCH+Wg`@)!cE|_TMb>LEk{aWIUIc9%9_3<70CftSPUhvQ{kTUGH*GMDJTE{w{lCz zgUSiW!B)yrrud#db|@apx2qhR{wAGOAk$C)0Is6CYn~cbg`2=K*`&2Z?HEr~cRecm zTP$avo-_(I39HoAIjii|-p5L+2rO|ESW=aYTM=cy%H!qL@ntJtO}!t);&ZsnnwddN z`q+B;<`WN~t?`A+tK-X32pO{cm7YZ literal 0 HcmV?d00001 diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@3x.png b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_bing.imageset/bing@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9d410b822d4f39d6ad4c5fa83d5c10c2883fd092 GIT binary patch literal 5563 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 literal 0 HcmV?d00001 diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_ddg.imageset/ddg@3x.png b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_ddg.imageset/ddg@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..527faecf87c132e84f69990bf8f98b2a6dfdb4c4 GIT binary patch literal 7751 zcmV-N9=PF&P) zdsq`!{{QC(yIXhH?LNJ1w{9=mwYpxD04lXw7rV7?TkEfWck}dHciZ)6yR=qWl}c-E z*=B7KMe#zV7)7HXR8x&u6!F5QTqc#6o5T1H#8}aNZ+r(}Eb6{9z8!u)=)N$%oqRuO z%o^X0yPvo#xziTJI)&bjYhaeo$>83Z-X-$0UH&@x08m1 zNG=u!s^s#YW5=@|#E&T+DU>T8FaI|8shSh$hNBS=FcV1lJX~ zuqs0}yXI8E%o_^z^y;$(f2hpNol-5&edfA6=ZVski;tD1oqMQ4t{k70koAD8z7gMo z%BPKQ=Qs_ZL?Q{mj%Phsd_HGltpc4@ehL#*pTY#!6u6L0*BQFTD4D80TO=qyg$b%M zw6m|DQckOoD<7B1WaC_o3GofEeA0XhBC%K;Sdl0nUno~TUVa9hTzO72%NaPHRJlSu zz4A0VQJb!OROuQnKTrL`bE4qF>aTIs5; zl2PBC_LU5|s!R6^U006fPnAlgKOId#c?YDUg)`Y4Hc}YInw$ZpOjSKA4fhIAJ`2-; zOPe!C@f|>46q}!N({iVH>5}KWAjxF1amsYHAjU#tuA6wR#NyX8OkC7?V45`rKB^5pD? zGgEP4W-2bsrj_Rpq9VVBuWX0^C|_o#;=*$&>gfrCpOP6{Fi9kmpPfrlPtT-HoD$zb z8O>t#XL8O&1o7zli5Hmq*GZRT*c3lV-T~_DF-(xXTlFyF1KEl5%Uils`KTWx?*et< z7$%Sm{1~v;Ve&v$k_VnjS4~r-;zGLQ2T{>bI^*VR!#O^je%)=0S)YqBjAXn_AD=#? zd=lX?J8_+r0y7c|pBf2BehpttKW7|Q%~r~k%!d@b0u$$#x8ujN9%N3?50iI+QlzM- zhlhvL@85YPJ8=%v8JT*LA0#isba?O|uXI=DqllNY6Q?lAB+79aQtfQT0bEFzJP{T7 zX-zjG>7wjRq{hv$eClBdCCh_Va4j(%PYzn zR^F&;UsY4xy81>%`>M*)+y9HJ>Xzl4uUvFmRyg;>5p^)%V|FE`|5Fd(!nAMBJv6Fd zl1L;0=?4pEjux1{KT-6Y7Oj7+t*Pe=v%z}KZU>bBz$O4-CxoyELb4Y^*aHCU001=F ztoAaK(Q>M#p*srAsd+gwO*4=0Ik*dyTw3rn;)P2cXD}Vxf8`P8BxJ*IfQ(Vzi=4G_ zLYfz>yigTZf3tm^vCnb_0N6neH0VN<0YJdUKArh^O?B(Lmrj=~_%=xu#N{}-@C!W- zNB0-Z^v0!*6OhDWao~{zYz7migNdlfS9B^x8+xm@?R~4&u7(gATmVBr2<;G(HVC1e zBuT;vXaE4%Ycg2BFDq#jrya#Y_?{zO%vdBRXVdT5aSjt_St&75K0f^rCh$d=j!4zP zcwXIWx*p?E2uULy3!2^OKRR^C+ z(S}~is`}$qykSL0n?BxdvsaQNX`;6WAvBpy_A7XP-7>!C%?4EZAxw}c8L&;jX?Efa zrlSey99{R}6u3p^RV@!5jKB;~Pn-!Fo z;6IA_^g&`GDq_Y&%Kf`KZedDD$a>J1K$1$;!PiO~-*IH5{s3F8_M)1awl%HIy03IP z^GT!8dcLpEe7w1__cI)?Uvcc1X5L8pOG(j&Ha2#DN)X^CZ7oHZ&9?l4g4$O`3ae*e zQcd$|n3DJBO!Os~^786lv)e%>?b1frtagn?b9;GnWAA5Hvt460+f;TtsDhB}hLAJ? z0NZsvM%krH*Z*`xstz7*pN9@%AvHA}?-2yJO#{kqFj&rIWR$+(D=-~6fD0uO$Jc zXw4!Bc$-77?ddV4rle>?eF3JV zB+V=i_nWwbY1=l%BLfDT;D9O4F_}GXPI`~yoISL2hpF1y_6YjUw%KgYJAL}v0%pCW zBvp_~RlmY&wU?V5`hYhUc27k#Ww#-dWyuOJ9eL)+B6rO`C}Wl&vr z{N!ezgZxQr|3CtL5w4xhc)pHTnEF#>T%7Xp_;_4MS6mz_8l*i8vDJyA9dlKOMMqM! zp?baP%-zcyG}PDkMDAf}N296#i_K=QcH>?gC9BzN&pms#da=9XO-wAD+u3Q{Pg{(e z+u97f-1dXJa>rkLP*HpWE~K<`Cnk_^w|U7OO!4u#Pq_t?2eoGpD!O#3?o|L_=iNoO zy(l?ZHIG^M(4nG`o*r|mqn-^yvX8dDVarSwv)Nu~wc4?!rk;NfXIv^({R#j;Gj-d> zY$ghi9MOh)+dpw}sE8h)y?Zf1Y%FIVN#Qaxp_BQBY2Q99q@khb3)*_e($v%=VXJ#C zyLvG}fI0|CtHEHoVlY_G+iakgd9RJO$=PYO5}4I$#|#F`m4gQh=ej$tSMd!~d^|4PwvDr$aPDB*7N0+Ldps_rD<%#Vc~eQrnt29;{Ty}KA_&l; z%&%Lobk6(Z)R2p~z4B!r})qM|K)IAg1+>xzVsG&r)8 zsijRH9~-X<^0to##V7{*t?$9KOEryem`fr0O zo$IKq;}GGv72O9_I z+LJfI=V02EkT-*Gm~snlE(ZWMQ5i&Uuv|z;(hLgNp8e|J>o+^s(s#x!R-3l+diz?F z$(HW~D6*rg?@;P@r7!gKSdS9~X!t&>_CJV=0*$!SS-P_EiwV9tR-y z_DXsPIN{SC{b+N!zq!e`g0t2w{(=xcP1A5p8Hj_KlaS z>$*1R4c1Jn6;zq5_M*nt-k7B1yID~xEe+Kht>-D2Y&KAN>A!Wa4ww(qN6h)UlAAuG z$7g#yF8pdgI??A~8ZgMAVDgZzUTs|s0NLvR#Matw*z2rrO8V7>7K^=v0g1DZ@Um?c z=yf{tag)h*#jzHm03-l_?H!%wZw?(QeU9pHzf>El(_6o%Wv1(wFW0^1Z67gX6dS9Y z-L9I=H%uiZEvo>aWu|sxqO-s1q-4!Jz21`PE<7&Y;Zf@@2mtIcn{9a|r7izp z_9vB=h8hgk3pAK2FJ7#Fg>RU)Z|CfDOE_*5Bdu ziiIY#4W(eRSnS1$vp1G_+ed?9v;*VnD|fhq>B}AJ>3qX-jZQ3Sk9ZQ1a3ClH62~XL+ZlTH)Ho@F;7 z{#)!mEM&*m_?%sP(YaJRTVqv0vHS8vcI_>kyW?wo&em8}5VJ3JQS;vj0ya}wv!~be z-QL8)xm^2T*f7NvKJIfceIA!Pg$<@C$0WAU$|zdtY|>PH=K1vF^tQIdprT!gg>!rK zmQxf=0K)bws#|Y3YxBFTnwK5#=*S^p0*-fJb@h#XpI^$YS)P%7PLJLWfHUMCczR#*SnQ`MKdOwH0Eqy_!w`5Rl z5(H>cX>PyeZU3;r^pQl#)%P}W2h(R?bUyHA}Pde|){G$9&XggLMGFE(l2j0I&}L*kQ4O8@+n#DZI4h zAIv^B$Et$z@!M|!0J^D5oXKR*+i?J&!#7NlotWU0PvrEUy&owDoWRr%)F#Qr$9w^% zuM#x#x_hjtce4{T-)hiFHpi-h201of6;yJq<2_d&i~|66oxf7IEGh;SZHZF{A3I&W zSfy=VSz6h)=4wU9`?>0-H;FX zvu;kJn&!8e=Q)FiS*M_|;co;18fasw{@wv6ABx6d?mt#G-)OQIxLAB!Z{F5@-VexD zRgfaP_RrYW*3~;%+8Y4sxtgVY2HR!w?gI*ajjg&plHL4V;^?u7+>Q%B+J?2YiBbD%!ku9$Et#^pe=tTz}<`kA!)o(-}zbeE-ZvzH##;yq@%~2;sPeJ zyVrbT>pm=G-;t8%%d6TWELM970brL>-SnojF~lD%dA_a7c!1UpVKUh<*>~k(eEpFz zW3%bY+-EofiCdTu1PNHTO*xG@;0-aT=w8Ki3fpT@jB_^c!a{y*(Qk+F?&D528@N?e z(eXYLs9O!XFCc_YZ|)KVY-nyZ?CtI~r%|_S0Dy+#%CeGDe>)Ys~80+U1{8^;_ppFl;%s)7_(>XsSJHWf+xSc#1Qw{JD{{UcR~% zs3<+V_Rjw&b&MMk3?bG6^( z*t5EBvDz!|e7_~xT~yKWeq^jF=&NsvoIxy z`Hrs>qyVwm2vFDBVLqhOSC^t0IP|W>b6-WsMPmU7f&_f@k@8Xcpd+Gj z;XfTv@U4@Xb+795)^p&_dS<{!PZ(d+MBV(vw+ni4xxqWz(m7wV~&78~*2Ziy_`*A`0yUY=e+A zK?sKei-3?c5Cm+}n{0Wtw{>62FW0}eaR)w!?>Vt)U>xwN9A_oZ!h|45!0OKn{xBMV zq9pkSdk!sXUv;xZAK%k!Ib$^1^DS0;iNyx0EH+SWv4TpI1r+re?73Y%rtfYw>bG6O zZ@=}ij{?L7(&}hj`1dWGJ#^_3CN6;LALM&6*l(E=@pYgmeU@-_UP4OMACI1?dHLjp zx>x1d^{=H}sC)I0;>MEQsTD75-di}A?=g-9q}9>5@NF+#;yBMvVXI{0Rz+)PGbgjk zF;Q0~Q%olfbq-q{S8~?pQ0+U@NXF#Oc!%33)At`pID4$gyD%XL5)dAfJ%J4-zq}*5 z-`|yJW{J7|LR7E7)DM(cEDrpC5^TmGpthi*VJV6sXUD03)1B(Ch@#$ySdG ztzz`G@*dCk)Hs~f;zmqguly{B ztM3zV8zioQ>L0u~{PM5e%}#!C3({XCs%c?ilAm}0B(K6W5U9`bXZ$dE7o<0%ap7Cs zJ<2p}kUR#ISRxP(DPC~fL1|;QxG#J;`(kCBB2@%VP7_|J|sX zE&g!8@1S@BB%gz608npiP)>3N)T>dbXbA^;m7yh!lI=Bm>28}`jMG`a)N5>hTD}Pr zy#A5L_LDe+$>TtUNhCj65t%>L8BkmVX{^YZk5+uDcmzQZPcFDQ0m+j<_5T%xgiC+A ze52}FKTyL5Y3YW%2?*lRcW#`5qFlrxdddG`v`Xce0uUfrmg9d>7pG%7(tJUrOD z3rDdy@WqWePdEc=X(TQT+u(3Ey`+naK(e(xRG-d{u^k@)L`x%a;me!QSzdbA<}r{c z^BPbue}F#r@+Qr!rIEOBF+=@8c~e8d!d7>LVuNULBraU?FKo&J&+j9R377^!HD4_M z`JxT#=?f!qp)+|MDi6x_Je8BYu(RzokSOyiP_IN}J@De%oQW^2#{^>;C}(q9u(5FF z3lUkrVccu;21s6k3GvcIXpR#HF5Rel_)ji?8jWBLHJ3lF#ixda4fq(zm;;G2F9U@H zgsqZ|3yV-bxoD$mwmU#Q?<9!Nvy^l>J9aN^($5?658@-$w6Kqqk1{^kHfBMh%mvFo)IrMVkWkuS)du`Z0nh0m|enaHv>@)ktAfrJb(D33xF5)%H?u<*=B z=WkR!>u#XtIphs^sJ`48SJ)=atcB|fo@RNc=1qurhY3NvKiR>VN-Q7$LPXvSccJoB z<{C-=&uvgnVtldteG3w0-k$VesKnyHg=@||6tceHY2n&}ne!rWVNe7voELF7BlRl+ z7X~^09pp?Av@(M6e`dW1me(1_sXjy3V}f~+_|%XMc@qS05BL%ZJ|XfMkSOCHD2K#i zap3%o*$>ZOr=1qO9uo`*I2U3<XVsUeMKCvWljhRA0@LJ)qP;xbzy z{aH)$v*$lR9}~TgO_}pA&8(1h+S$QtFu_POSnzsG5WEHxgsfA|4voNO%zH2QnT0FQ zJtQ8y$>?hk`7}s$P*6nPZ)UB>ej5^=H(~wyYrwUm(sG(Y^-I zr~-*HzMVBJuskfj=RT@IqKt2+@c|g$a~hK%QO39PJP8=zW4*6Hq8s0iyq`5Djc=#k zj~dg)w{!0&-518UlgGO5TjSgDV@ZBP_z%KZklz@_cR)s?{N}>=4$f$j--cm)2g}#w zHx7*NAo_y*<{{%duzq;Ppz$4WKSX2P_=dp`%@{Vmq4C4xH@^+n{y$50Xbw*R|D6B; N002ovPDHLkV1n78)gS-> literal 0 HcmV?d00001 diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/Contents.json b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/Contents.json new file mode 100644 index 000000000..1cc77a273 --- /dev/null +++ b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/Contents.json @@ -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" + } +} \ No newline at end of file diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@1x.png b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..62e7c3dd4a812d59c8e2d291489173611b7035a9 GIT binary patch literal 861 zcmV-j1ETziP)F|7{F)eB6{-d#gk|U{how&5h*A{u&9Fw1tCI0hmB=wm7swoSeT+!5SDhW4l!)f zV5=bu;bFb(v;9gWM1uY(5kYuJ%{1)K&g-%R<2W<#?Ye?}@MGV6?|t9<@eMnY^dCpy z02~>Sipy16rfezE#u8lO0Gh(oyLEbhAeuB>c?7-MW}>*tg`Zzt+lJA1@p2(cIfS4eXRMWeQL5z}Pb zj4@`)rwM52`V@#}Zt17nPh+<((<<(xv<+~;$=KB^`t6pm8j z$K$8Vrx;_VX|g}gJxhq!L)8$5?&KP|LW+Qp{bI%#d$+QF^W&!t)p{7AoL6)oDWk{33`SRE)2aq<}sZ;LjF<;!kI872f^wiD&r*- zkR(a&QV_Zngp(mkxPd?=R2DP@bH8}X00000NkvXXu0mjf5#xw6 literal 0 HcmV?d00001 diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@2x.png b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0085500fb816e71c3ea6eb3bd7af3ffdae584a64 GIT binary patch literal 2082 zcmV+-2;KLIP)npS*W=%o%|4v?>evPBtqb-)Xo~z*H<+xp8cbRc;JhW0iaI zw#O>>gl!E~>`4gOR4f#42s5!Y7B?8D)441bj@6F#oqcG$FS+qbl)$Ajb|$elbt<(o z>~hr<0n8Ra0sug8I2_d%P7kd5dz3({x%k$=!;&a1=ZIA{AOQd%NTRfSG&;0?sYwq@ z80AYLu#uDT6&$ci4kQ2ogs{t1^N+sN2BRo?qIJwzI96*Bt7J$506@6#=D7z+lt5*y z!e~W3MoLO;a5|mKN(p5cNEF5Dq?FuPY@9+^aciew@qi>rx`*@<$bx$?!V*TfM-iz& zmg=kCuF+39{@@#ft4%@`1xa|P^PQE62!SMg~ zf-(&BL4-h-cY81@cNW!iJhjdQ6gMP6lB9d=2Bd`*JNe!ko~y~wMS2lXH%9Ls&!$_E z<9W8Lldq4(?X12tU5Wd6ttMSS005!ycyePbLSQUH;9t5ivTIn4u?T?dpUnOj9Jm#ZckAut*tQ0m60Qo?GE9*sX>Wi{zS>N}O%P>D!N zD6^|c=fzrD9t{x~4G|~>F{-rWY7Y+@d9^c!)EgXH-y0&ZH$-4h5Ti;=Bt&2&WN0<% zMiLwjM>QLu+!N)2bUHk+%IIn;h!j3Nu!;@P9mI%dPQ0F~|L|`Uzq~R1pTjdVbJEQ1 zZ{C=ky!}ctarI}%j-IXKJzgY4;EC?xN4X<0Af8CQr!F>pb#pdMsr8@#h`?YFBOZA_e)*@F44uq}qizcebd1;7Y%a%+_1~`-Nyn>N ztd=Lz+izcbB9o!F^a9DUEMFP@{5jr8p-}FRU+YN0;Ms?GAss!MtV^de<7$MtxrMW1 zV^g~miScbiL;v1BF>#|kou;42vMi5`eD*6|KuV~tuGA)-r(9vA*Ir9*?Cd14GeF>x z4vdZ*(MZ1Ss$9Ev^LKZxl8?T4Az%M^d~C~+;1b8|$TK$E9?V8nXJ?4OPW{)V!bpJt zfq?*l9UT~1&7C_7V@jZjiD?gy;~EW{6E`G(fIxqMKwk$&RuYMfHp;S08BjW%`Ql(8 zS!eaQX2Ry=a)oPbh4jI>@n+>Jy8h*CP^+IT%Xeg1&g2WFbcPp_D28kKAo&UO`w8^< zFtQSI@$+9VKGkj=(CU}P$lEBD=X3qp#0}QM=Cs!@-OB~Z>nG6bCs6cZWF-U1YtJet z``P5z9a{Z#AkA5=h0W>Eq1=Bz*#qh1=}S*2Cp$N{FsjvW>iTSOYI>%NWpZk!OSxY< zow?2nN&MeE1$>Y^K8&nnzYn8yhE8YanvrE$j=le{?S=OH=<2N&CDOG|zxspKTG*Vp zy}Gdj@_?HDa<)rWyuwjR=K`;f{Aj6tC|!K|9SjaP*bZsm!Ngj(pFlSUq=UiX21?~` zRF|3b$DiEXd)ErOa^tsZp!xZQ%T{af_%LGg;fB;ArdIMo^7t@1|KasrOI?&HrSo~7 z&Ug=}>Uklx{c&i$4j_F<^)6QpLu&J3#3Lh@r`wdLosLFBfBxs=JjP~od0EWeFHjIk z7nJ)I0$K76{-XG8bQLRN^k)BfGo|uuA)QQy-tfLU+`#s0(=&#siVCU4OQ3<{|AeAy~4$uD{e_tn%Zlo#zfWQW*WGGg@(N&}ysr^uV1si0ih*6~__e(x7 z_=wR}WO_C2+>g=D{TS`^WdCJ9n|Z9Olil*-e(1oC0LTGM}!*V#p>c;l- zk2PfrZYnaAa-1gjqL=xi16hIs00@n{;}57Opag4Fq(SvFd+bm>Rz9zBZ1zsNq(GLT z002T$>);wKtR^>s4T?$YiPkZG(mMEv;%~9CeS6X@)FP~U*TAZVmxdp$Yay`CO<-M1 zHf~ka+ch36MJ5NkY&D~P5M-s2X% z@h-TODQPSBWNibB|RR910 literal 0 HcmV?d00001 diff --git a/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@3x.png b/Cliqz/Resources/Common.xcassets/ReactCards/ic_ez_google.imageset/google@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..0bc74b1d19b1ce2500177670b4ca90f6f5c196f5 GIT binary patch literal 5937 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 T55TT~00000NkvXXu0mjffrMCO literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 2889b2781..7625c87f0 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/js/i18n.js b/js/i18n.js new file mode 100644 index 000000000..648302a08 --- /dev/null +++ b/js/i18n.js @@ -0,0 +1,25 @@ +import { NativeModules } from 'react-native'; +import console from 'browser-core-lumen-ios/build/modules/core/console'; + +let translations; + +export default function t(key) { + if (!translations) { + const locale = NativeModules.LocaleConstants.lang; + switch (locale) { + case 'de': + translations = require('./localization/de.json'); + break; + default: + translations = require('./localization/en.json'); + } + } + const translation = translations[key]; + + if (!translation) { + console.warn(`Cannot find translation for key "${key}"`); + return key; + } + + return translation.message; +} \ No newline at end of file diff --git a/js/localization/de.json b/js/localization/de.json new file mode 100644 index 000000000..1aaf5f583 --- /dev/null +++ b/js/localization/de.json @@ -0,0 +1,35 @@ +{ + "search_no_results": { + "message": "KEINE TREFFER GEFUNDEN" + }, + "search_footer": { + "message": "DIESE SUCHANFRAGE IST ANONYM" + }, + "search_alternative_search_engines_info": { + "message": "Lumen Suche verlassen?" + }, + "onboarding_title": { + "message": "Neu: Anonyme Suche" + }, + "onboarding_description_line1": { + "message": "Jetzt aktivieren um anonym zu suchen." + }, + "onboarding_description_line2": { + "message": "Dies kann jederzeit in den Einstellungen geändert werden." + }, + "onboarding_action_accept": { + "message": "AUSPROBIEREN" + }, + "onboarding_action_reject": { + "message": "NEIN, DANKE" + }, + "onboarding_result_with_query": { + "message": "SUCHE AKTIVIERT" + }, + "onboarding_result_without_query": { + "message": "EINFACH LOSTIPPEN" + }, + "test": { + "message": "de" + } +} \ No newline at end of file diff --git a/js/localization/en.json b/js/localization/en.json new file mode 100644 index 000000000..ee1ef0c10 --- /dev/null +++ b/js/localization/en.json @@ -0,0 +1,35 @@ +{ + "search_no_results": { + "message": "NO RESULTS FOUND" + }, + "search_footer": { + "message": "THIS SEARCH QUERY IS ANONYMOUS" + }, + "search_alternative_search_engines_info": { + "message": "Leave Lumen Search?" + }, + "onboarding_title": { + "message": "New: Anonymous Search" + }, + "onboarding_description_line1": { + "message": "Activate now to search anonymously." + }, + "onboarding_description_line2": { + "message": "This can be changed anytime in settings." + }, + "onboarding_action_accept": { + "message": "TRY NOW" + }, + "onboarding_action_reject": { + "message": "NO, THANKS" + }, + "onboarding_result_with_query": { + "message": "SEARCH ACTIVATED" + }, + "onboarding_result_without_query": { + "message": "START TYPING" + }, + "test": { + "message": "de" + } +} \ No newline at end of file diff --git a/js/lumen-onboarding.js b/js/lumen-onboarding.js new file mode 100644 index 000000000..e7a780567 --- /dev/null +++ b/js/lumen-onboarding.js @@ -0,0 +1,112 @@ +import React from 'react'; +import { StyleSheet, View, Text, TouchableWithoutFeedback, Animated, Easing } from 'react-native'; +import { XmlEntities } from 'html-entities'; +import t from './i18n'; + +const styles = StyleSheet.create({ + container: { + backgroundColor: 'white', + borderBottomLeftRadius: 9, + borderBottomRightRadius: 9, + alignItems: 'center', + justifyContent: 'center', + paddingTop: 35, + paddingBottom: 25, + }, + tryNow: { + backgroundColor: '#3647D0', + borderRadius: 14, + alignItems: 'center', + justifyContent: 'center', + height: 36, + marginTop: 20, + }, + title: { + letterSpacing: 0.25, + fontSize: 18, + fontWeight: '700', + lineHeight: 21, + }, + body: { + marginTop: 8, + fontSize: 13, + lineHeight: 16, + fontWeight: '500', + } +}); + +export default class Onboarding extends React.Component { + state = { + isClicked: false, + } + + get checkMark() { + if (!this._checkMark) { + const entities = new XmlEntities(); + this._checkMark = entities.decode('✓'); + } + + return this._checkMark; + } + + componentWillMount() { + this.animatedValue = new Animated.Value(0); + this.interpolateColor = (from, to) => this.animatedValue.interpolate({ + inputRange: [0, 150], + outputRange: [from, to] + }); + this.interplateWidth = this.animatedValue.interpolate({ + inputRange: [0, 150], + outputRange: [95, 36] + }); + } + + onPress = (choice) => { + this.props.onChoice(choice); + Animated.timing(this.animatedValue, { + toValue: 150, + duration: 250, + easing: Easing.ease + }).start(); + this.setState({ isClicked: true }); + } + + render() { + // TODO chrmod: translations + const tryNowText = this.state.isClicked ? this.checkMark : t('onboarding_action_accept'); + const noThanksText = this.state.isClicked ? (this.props.hasQuery ? t('onboarding_result_with_query') : t('onboarding_result_without_query')) : t('onboarding_action_reject'); + const animatedStyle = { + backgroundColor: this.interpolateColor('#3647D0', '#AEAFFF'), + width: this.interplateWidth, + }; + return ( + + + {t('onboarding_title')} + + + {t('onboarding_description_line1')} + + + {t('onboarding_description_line2')} + + this.onPress(true)}> + + {tryNowText} + + + this.onPress(false)}> + <> + {noThanksText} + + + + ); + } +} \ No newline at end of file diff --git a/lumen.js b/lumen.js index e3fa63240..af69f6f5f 100644 --- a/lumen.js +++ b/lumen.js @@ -2,7 +2,7 @@ import 'react-native/Libraries/Core/InitializeCore'; import './setup'; import 'process-nextick-args'; import React from 'react'; -import { AppRegistry, StyleSheet, View, AsyncStorage } 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'; @@ -13,10 +13,18 @@ import SearchUI from 'browser-core-lumen-ios/build/modules/mobile-cards/SearchUI import SearchUIVertical from 'browser-core-lumen-ios/build/modules/mobile-cards-vertical/SearchUI'; 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 './js/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'; +import t from './js/i18n'; + +const nativeBridge = NativeModules.JSBridge; // set app global for debugging +// TODO chrmod: get rid of startup const appStart = startup.then((app) => { global.app = app; + return app; }); const styles = StyleSheet.create({ @@ -25,36 +33,51 @@ const styles = StyleSheet.create({ flexDirection: 'column', backgroundColor: 'transparent' }, + footer: { + height: 20, + backgroundColor: '#656d7e', + alignItems: 'center', + justifyContent: 'center', + borderBottomLeftRadius: 5, + borderBottomRightRadius: 5 + }, + searchEnginesContainer: { + flexDirection: 'row', + justifyContent: 'space-evenly', + marginTop: 20, + marginBottom: 100, + }, + searchEngineIcon: { + height: 73, + width: 73, + borderRadius: 10, + overflow: 'hidden', + }, }); -// wrapper for a component to add top padding on iOS -function AppContainer(App, appStart) { - return () => ( - - - - ); -} - class MobileCards extends React.Component { constructor(props) { super(props); + this.state = { + onboarding: props.showSearchOnboarding, + results: { + results: [], + meta: {} + }, + hasQuery: false, + theme: 'lumen-light' + } + this.cliqz = new Cliqz(); this.isDeveloper = prefs.get('developer', false); - this.appStart = props.appStart || Promise.resolve(); + this.appStart = appStart || Promise.resolve(); events.sub('search:results', this.updateResults); events.sub('mobile-browser:notify-preferences', this.updatePreferences); events.sub('mobile-browser:set-search-engine', this.setSearchEngine); addConnectionChangeListener(); - } - - state = { - results: { - results: [], - meta: {} - }, - theme: 'light' + this.eventEmitter = new NativeEventEmitter(nativeBridge); + this.eventEmitter.addListener('action', this.onAction); } componentWillUnmount() { @@ -62,15 +85,27 @@ class MobileCards extends React.Component { events.un_sub('mobile-browser:set-search-engine', this.setSearchEngine); events.un_sub('search:results', this.updateResults); removeConnectionChangeListener(); + this.eventEmitter.removeAllListeners(); } - setSearchEngine = (engine) => { - setDefaultSearchEngine(engine); + onAction = async ({ action, args, id }) => { + const [module, name] = action.split(':'); + 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, + }); + return; + } + const response = await inject.module(module).action(name, ...args); + if (typeof id !== 'undefined') { + nativeBridge.replyToAction(id, response); + } } - _setTheme(incognito) { - const theme = incognito ? 'dark' : 'light'; - this.setState({ theme }); + setSearchEngine = (engine) => { + setDefaultSearchEngine(engine); } updatePreferences = (_prefs) => { @@ -78,36 +113,107 @@ class MobileCards extends React.Component { this.appStart.then(() => { Object.keys(_prefs).forEach((key) => { prefs.set(key, _prefs[key]); - if ((key === 'incognito')) { - this._setTheme(_prefs[key]); - } }); }); } - updateResults = results => this.setState({ results }); + updateResults = results => this.setState({ results, onboarding: false }); + + 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() { - const { results, suggestions, meta } = this.state.results; + const { results, suggestions, meta, query } = this.state.results; const appearance = this.state.theme; const layout = 'vertical'; const SearchComponent = layout === "horizontal" ? SearchUI : SearchUIVertical; - return ( + if (this.state.onboarding) { + return ( + + ); + } else { + NativeModules.QuerySuggestion.showQuerySuggestions(query, suggestions); + return ( - + + } + separator={} + footer={} + /> + <> + { /* TODO chrmod: colors and font sizes */ } + { results.length === 0 && + + + + } + + + {t('search_footer')} + + + + {t('search_alternative_search_engines_info')} + + + { /* TODO chrmod: list + send openlink event onclick + real pngs */ } + this.openLink(`https://google.com/search?q=${encodeURIComponent(this.state.results.query)}`)} + > + + + this.openLink(`https://duckduckgo.com/?q=${encodeURIComponent(this.state.results.query)}`)} + > + + + this.openLink(`https://www.bing.com/search?q=${encodeURIComponent(this.state.results.query)}`)} + > + + + + + - ); + ); + } } } -AppRegistry.registerComponent('ExtensionApp', () => AppContainer(MobileCards, appStart)); \ No newline at end of file +AppRegistry.registerComponent('ExtensionApp', () => MobileCards); diff --git a/package-lock.json b/package-lock.json index acd701cb6..5dc919ca6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1075,10 +1075,10 @@ "requires": { "@babel/polyfill": "^7.0.0", "eventtargeter": "0.5.0", - "sync-promise": "git+https://github.com/brettz9/sync-promise.git#25845a49a00aa2d2c985a5149b97c86a1fcdc75a", + "sync-promise": "git+https://github.com/brettz9/sync-promise.git#full-sync-missing-promise-features", "typeson": "5.11.0", "typeson-registry": "1.0.0-alpha.26", - "websql": "git+https://github.com/brettz9/node-websql.git#5149bc0763376ca757fc32dc74345ada0467bfbb" + "websql": "git+https://github.com/brettz9/node-websql.git#configurable-secure2" } }, "@cliqz/url-parser": { @@ -14827,8 +14827,8 @@ } }, "browser-core-lumen-ios": { - "version": "https://s3.amazonaws.com/cdncliqz/update/edge/lumen-ios/master/13.39.0.25.4908295.tgz", - "integrity": "sha512-nbPFmRkmZYo2rI7oqG9EFeSpDAvI4gNu1v+unDpWmnmE7Q4wY1XQSu/1eM4UhhQvM9BOt1g0HBn/6DKTGJMMpw==", + "version": "https://s3.amazonaws.com/cdncliqz/update/edge/lumen-ios/master/13.39.0.50.76d6dc1.tgz", + "integrity": "sha512-HKIfolwrHCWUJ8FxgakffgfEJrhYH2NxC6iIOoGazM1HD6SfCk8i2h0jU2O3K3MXjV+nrbYoqOFYmTXYXNEVdw==", "requires": { "@cliqz-oss/dexie": "^2.0.4", "@cliqz/adblocker": "^0.11.0", @@ -14871,9 +14871,9 @@ }, "dependencies": { "ajv": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.1.tgz", - "integrity": "sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -16987,7 +16987,8 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true }, "aproba": { "version": "1.2.0", @@ -17008,12 +17009,14 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "optional": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -17028,17 +17031,20 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "optional": true }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -17155,7 +17161,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "optional": true }, "ini": { "version": "1.3.5", @@ -17167,6 +17174,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -17181,6 +17189,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -17188,12 +17197,14 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "optional": true }, "minipass": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -17212,6 +17223,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "optional": true, "requires": { "minimist": "0.0.8" } @@ -17298,7 +17310,8 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true }, "object-assign": { "version": "4.1.1", @@ -17310,6 +17323,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "optional": true, "requires": { "wrappy": "1" } @@ -17395,7 +17409,8 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -17431,6 +17446,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -17450,6 +17466,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -17493,12 +17510,14 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "optional": true }, "yallist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", + "optional": true } } }, diff --git a/package.json b/package.json index b599fb5b9..60572dcbe 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,9 @@ "appium": "1.9.0", "browser-core": "https://s3.amazonaws.com/cdncliqz/update/edge/cliqz-ios/master/1.38.0.1b131.7bdc200.tgz", "browser-core-cliqz-ios": "https://s3.amazonaws.com/cdncliqz/update/edge/cliqz-ios/master/3.39.0.25.4908295.tgz", - "browser-core-lumen-ios": "https://s3.amazonaws.com/cdncliqz/update/edge/lumen-ios/master/13.39.0.25.4908295.tgz", + "browser-core-lumen-ios": "https://s3.amazonaws.com/cdncliqz/update/edge/lumen-ios/master/13.39.0.50.76d6dc1.tgz", "buffer": "5.0.7", + "html-entities": "^1.2.1", "https-browserify": "1.0.0", "page-metadata-parser": "^1.1.2", "path-browserify": "0.0.0",