Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deep linking (closes #331) #338

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3a1c7f5
Add incoming url detection logic, mapped to openItem
wilsonpage Nov 14, 2016
dd6097f
Add custom protocol handling
wilsonpage Nov 14, 2016
b085e9e
Add missing return statements
wilsonpage Nov 14, 2016
956defb
Add .postArray() method to cope with JSON array posting
wilsonpage Nov 14, 2016
86b891a
Change redux architecture to fetch on demand
wilsonpage Nov 14, 2016
2433cf5
Remove redundant metadata fetcher
wilsonpage Nov 14, 2016
3802873
Show loading indicator when resolving item
wilsonpage Nov 14, 2016
7d30fb2
Protect against navigator not being defined yet
wilsonpage Nov 15, 2016
cc911bc
Remove dead module
wilsonpage Nov 15, 2016
5f3404d
Change to use proper async redux actions for data retrieval
wilsonpage Nov 15, 2016
0875155
Fix loading spinner styling
wilsonpage Nov 15, 2016
f95b3f0
Listen for deep-links when app is running
wilsonpage Nov 15, 2016
e3ff64f
Add support for POSTing JSON arrays
wilsonpage Nov 15, 2016
54e19a6
Fix incorrect props mapping
wilsonpage Nov 15, 2016
ba5bc4d
Yarn lock not up-to-date for some reason
wilsonpage Nov 15, 2016
4b8ea0f
Remove expiring logic as needs to be moved to native scanners
wilsonpage Nov 15, 2016
4a04ea0
Moved network status logic into redux store
wilsonpage Nov 15, 2016
07b18be
Fix refresh logic to be based on 'nearbyItems' not 'items'
wilsonpage Nov 15, 2016
5e117dd
Add missing file for network checks
wilsonpage Nov 15, 2016
471894c
Remove unused callback
wilsonpage Nov 15, 2016
3d823ce
Fix tests
wilsonpage Nov 15, 2016
ba0c461
Add native linking logic for ios
wilsonpage Nov 15, 2016
14d6cc8
yarn.lock not updated
wilsonpage Nov 16, 2016
4eb9199
Fix broken unit-tests
wilsonpage Nov 16, 2016
9ef79f7
Rename files to match class names
wilsonpage Nov 19, 2016
fe35759
Use InteractionsManager to prevent render whilst animating
wilsonpage Nov 19, 2016
b72380f
Fix naming inconsistency
wilsonpage Nov 19, 2016
e8bf061
Don't change state when distance hasn't changed
wilsonpage Nov 19, 2016
0f723ff
Update yarn.lock
wilsonpage Nov 19, 2016
b165b89
Fix broken test
wilsonpage Nov 21, 2016
b3d4447
Remove redundant code
wilsonpage Nov 21, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,31 @@
<uses-sdk tools:overrideLibrary="org.mozilla.magnet.net.scanner" />

<application
android:name="org.mozilla.magnet.MainApplication"
android:name=".MainApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="org.mozilla.magnet.MainActivity"
android:name=".MainActivity"
android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- handles URIs that begin with "mozilla-magnet://item” -->
<data android:scheme="mozilla-magnet"
android:host="item" />
</intent-filter>

</activity>

<service
Expand Down
2 changes: 2 additions & 0 deletions android/app/src/main/java/org/mozilla/magnet/api/Api.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public void post(String path, Object data, Callback callback) {

if (match == null) {
callback.reject("no matching route");
return;
}

match.post(path, data, callback);
Expand All @@ -96,6 +97,7 @@ public void delete(String path, HashMap<String,Object> data, Callback callback)

if (match == null) {
callback.reject("no matching route");
return;
}

match.delete(path, data, callback);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeArray;
import com.facebook.react.bridge.ReadableNativeMap;

import org.json.JSONArray;
Expand All @@ -15,6 +17,8 @@
import org.mozilla.magnet.api.Utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ApiMagnetReact extends ReactContextBaseJavaModule {
private static final String TAG = "APIMagnetReact";
Expand Down Expand Up @@ -46,11 +50,39 @@ public void reject(String error) {
}

@ReactMethod
public void post(String path, ReadableMap data, final Promise promise) {
public void post(String path, ReadableMap map, final Promise promise) {
Log.d(TAG, "post");
HashMap<String,Object> map = ((ReadableNativeMap) data).toHashMap();
Object data = fromReactArgument(map);

if (data == null) {
promise.reject("invalid-data-type", "invalid data type");
return;
}

mApiMagnet.post(path, map, new Api.Callback() {
mApiMagnet.post(path, data, new Api.Callback() {
@Override
public void resolve(Object result) {
promise.resolve(toReactArgument(result));
}

@Override
public void reject(String error) {
promise.reject(error, error);
}
});
}

@ReactMethod
public void postArray(String path, ReadableArray array, final Promise promise) {
Log.d(TAG, "post");
Object data = fromReactArgument(array);

if (data == null) {
promise.reject("invalid-data-type", "invalid data type");
return;
}

mApiMagnet.post(path, data, new Api.Callback() {
@Override
public void resolve(Object result) {
promise.resolve(toReactArgument(result));
Expand Down Expand Up @@ -86,4 +118,10 @@ static private Object toReactArgument(Object object) {
else if (object instanceof JSONObject) return Utils.jsonToWritableMap((JSONObject) object);
else return null;
}

static private Object fromReactArgument(Object object) {
if (object instanceof ReadableNativeArray) return ((ReadableNativeArray) object).toArrayList();
else if (object instanceof ReadableNativeMap) return ((ReadableNativeMap) object).toHashMap();
else return null;
}
}
6 changes: 1 addition & 5 deletions config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ module.exports = {
title: 'Show distance',
},

'removeOldItems': {
value: false, // default
title: 'Remove old items',
},

'enableTelemetry': {
value: true, // default
title: 'Telemetry',
Expand All @@ -40,6 +35,7 @@ module.exports = {
'itemExpiring': 10000, // 10 secs

'metadataServiceUrl': 'https://tengam.org/api/v1/metadata',
'searchServiceUrl': 'https://tengam.org/content/v1/search/url',

'theme': {
'colorBackground': '#f2f2f2',
Expand Down
12 changes: 12 additions & 0 deletions ios/Api.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SwiftyJSON
protocol Api {
func get(path: String, callback: ApiCallback)
func post(path: String, data: NSDictionary, callback: ApiCallback)
func post(path: String, data: NSArray, callback: ApiCallback)
func put(path: String, data: NSDictionary, callback: ApiCallback)
func delete(path: String, data: NSDictionary, callback: ApiCallback)
func mount(path: String, api: Api)
Expand Down Expand Up @@ -60,6 +61,17 @@ class ApiBase: Api {
api!.post(path, data: data, callback: callback)
}

func post(path: String, data: NSArray, callback: ApiCallback) {
let api = find(path)

guard api != nil else {
callback.onError("Could not find route \(path)")
return
}

api!.post(path, data: data, callback: callback)
}

func put(path: String, data: NSDictionary, callback: ApiCallback) {
let api = find(path)

Expand Down
6 changes: 6 additions & 0 deletions ios/ApiMagnetReact.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ @interface RCT_EXTERN_MODULE(ApiMagnetReact, NSObject);
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(
postArray:(NSString *)path
data:(NSArray *)data
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(
put:(NSString *)path
data:(NSDictionary *)data
Expand Down
10 changes: 10 additions & 0 deletions ios/ApiMagnetReact.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ import Foundation
}))
}

@objc func postArray(path: String, data: NSArray, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
api.post(path, data: data, callback: ApiCallback(success: { result in
resolve(result.rawValue)
},
error: { (error) in
let err = NSError(coder: NSCoder())
reject("get_error", "Error resolving \(path) with \(data)", err)
}))
}

@objc func put(path: String, data: NSDictionary, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
api.put(path, data: data, callback: ApiCallback(success: { result in
resolve(result.rawValue)
Expand Down
11 changes: 8 additions & 3 deletions ios/ApiMetadata.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,25 @@ class ApiMetadata: ApiBase {
//
// data["objects"] = elems
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*Update


override func post(path: String, data: NSDictionary, callback: ApiCallback) {
override func post(path: String, data: NSArray, callback: ApiCallback) {
guard System.connectedToNetwork() else {
callback.onError("No internet connection")
return
}

let url = NSURL(string: ApiMetadata.SERVER_URL)
var urls = Array<Dictionary<String,String>>();

let parameters = ["objects": (data.valueForKey("objects"))!]
for url in data {
urls.append(["url": url as! String]);
}

let body = ["objects": urls]
let request = NSMutableURLRequest(URL: url!)

request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(body, options: [])

Alamofire.request(request).responseJSON { response in
guard response.result.value != nil else {
Expand Down
4 changes: 4 additions & 0 deletions ios/Magnet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient",
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS",
);
INFOPLIST_FILE = Magnet/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
Expand Down Expand Up @@ -1027,6 +1028,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient",
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS",
);
INFOPLIST_FILE = Magnet/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
Expand Down Expand Up @@ -1086,6 +1088,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient",
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/RCTLinkingManager.h",
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
Expand Down Expand Up @@ -1128,6 +1131,7 @@
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-linear-gradient/BVLinearGradient",
"$(SRCROOT)/../node_modules/react-native/Libraries/LinkingIOS/RCTLinkingManager.h",
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
Expand Down
6 changes: 6 additions & 0 deletions ios/Magnet/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "RCTBundleURLProvider.h"
#import "RCTRootView.h"
#import "RCTBridge.h"
#import "RCTLinkingManager.h"

// Include the project headers for swift code. (<project-name>-Swift.h)
#import "magnet-Swift.h"
Expand Down Expand Up @@ -70,4 +71,9 @@ -(void)application:(UIApplication *)application didReceiveLocalNotification:(UIL
[self.bridge.eventDispatcher sendDeviceEventWithName:@"notification:applaunch" body:nil];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
}


@end
11 changes: 11 additions & 0 deletions ios/Magnet/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@
<string>1.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>org.mozilla.magnet</string>
<key>CFBundleURLSchemes</key>
<array>
<string>mozilla-magnet</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>7</string>
<key>LSRequiresIPhoneOS</key>
Expand Down
6 changes: 2 additions & 4 deletions ios/NotificationsHelperIOS10.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@ class NotificationsHelperIOS10: NSObject, UNUserNotificationCenterDelegate {

private func fetchData(url: String, callback: ((JSON) -> Void)) {
let api = ApiMetadata()
let urls: NSArray = [url]

let item: Dictionary<String, String> = ["url": url]
let objects: Dictionary<String, NSArray> = ["objects": [item]]

api.post("metadata", data: objects, callback: ApiCallback(success: { json in
api.post("metadata", data: urls, callback: ApiCallback(success: { json in
callback(json)
}, error: { (err) in
debugPrint("Could not get metadata for \(url): \(err)")
Expand Down
50 changes: 50 additions & 0 deletions lib/api/fetch-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use strict';

/**
* Dependencies
*/

const { searchServiceUrl } = require('../../config');
const debug = require('../debug')('get-item');
const api = require('.');

/**
* Exports
*/

module.exports = function(url) {
return Promise.all([
fetchBeaconData(url),
fetchMetadata(url),
])

.then(results => {
var item = results[0][0];
var metadata = results[1][0];

return {
...item,
metadata,
};
});
};

function fetchMetadata(url) {
return api.postArray('metadata', [url]);
}

function fetchBeaconData(url) {
debug('fetch beacon data', url);
const request = new Request(searchServiceUrl, {
method: 'post',
headers: new Headers({ 'Content-Type': 'application/json;charset=utf-8' }),
body: JSON.stringify([url]),
});

return fetch(request)
.then(res => res.json())
.catch(() => {
debug('no beacon data', url);
return [];
});
}
File renamed without changes.
Loading