diff --git a/app/src/component/AppNavigator.js b/app/src/component/AppNavigator.js
index 8370793..ae67210 100644
--- a/app/src/component/AppNavigator.js
+++ b/app/src/component/AppNavigator.js
@@ -20,6 +20,7 @@ import {
AppState,
AsyncStorage,
BackHandler,
+ Linking,
NativeModules,
TextInput,
ToastAndroid
@@ -109,7 +110,7 @@ class AppWithNavigationState extends React.Component {
componentWillMount() {
AppState.addEventListener('change', this._handleAppStateChange);
BackHandler.addEventListener('hardwareBackPress', function() {
- const { dispatch, navigation, nav } = this.props;
+ const { dispatch, nav } = this.props;
// There should be a better way to check this
if (nav.routes.length > 0) {
const subRoutes = nav.routes[0].routes[0].routes;
@@ -130,9 +131,14 @@ class AppWithNavigationState extends React.Component {
}.bind(this));
}
+ componentDidMount() {
+ Linking.addEventListener('url', this._handleUrl);
+ }
+
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
BackHandler.removeEventListener('hardwareBackPress');
+ Linking.removeEventListener('url', this._handleUrl);
}
componentWillUpdate(nextProps) {
@@ -174,6 +180,17 @@ class AppWithNavigationState extends React.Component {
}
}
+ _handleUrl = (evt) => {
+ const { dispatch } = this.props;
+ if (evt.url) {
+ const navigateAction = NavigationActions.navigate({
+ routeName: 'File',
+ params: { uri: evt.url }
+ });
+ dispatch(navigateAction);
+ }
+ }
+
render() {
const { dispatch, nav } = this.props;
return (
diff --git a/app/src/page/splash/view.js b/app/src/page/splash/view.js
index 0827092..0ff8658 100644
--- a/app/src/page/splash/view.js
+++ b/app/src/page/splash/view.js
@@ -1,6 +1,6 @@
import React from 'react';
import { Lbry } from 'lbry-redux';
-import { View, Text, NativeModules } from 'react-native';
+import { View, Text, Linking, NativeModules } from 'react-native';
import { NavigationActions } from 'react-navigation';
import PropTypes from 'prop-types';
import splashStyle from '../../styles/splash';
@@ -16,6 +16,7 @@ class SplashScreen extends React.PureComponent {
message: 'Connecting',
isRunning: false,
isLagging: false,
+ launchUrl: null
});
}
@@ -51,6 +52,10 @@ class SplashScreen extends React.PureComponent {
]
});
navigation.dispatch(resetAction);
+
+ if (this.state.launchUrl) {
+ navigation.navigate('File', { uri: this.state.launchUrl });
+ }
});
return;
}
@@ -78,6 +83,12 @@ class SplashScreen extends React.PureComponent {
if (NativeModules.Mixpanel) {
NativeModules.Mixpanel.track('App Launch', null);
}
+
+ Linking.getInitialURL().then((url) => {
+ if (url) {
+ this.setState({ launchUrl: url });
+ }
+ });
Lbry
.connect()
diff --git a/app/src/redux/actions/file.js b/app/src/redux/actions/file.js
index c248f17..0a1461c 100644
--- a/app/src/redux/actions/file.js
+++ b/app/src/redux/actions/file.js
@@ -34,7 +34,9 @@ export function doUpdateLoadStatus(uri, outpoint) {
},
});
- NativeModules.LbryDownloadManager.updateDownload(uri, fileInfo.file_name, 100, writtenBytes, totalBytes);
+ if (NativeModules.LbryDownloadManager) {
+ NativeModules.LbryDownloadManager.updateDownload(uri, fileInfo.file_name, 100, writtenBytes, totalBytes);
+ }
/*const notif = new window.Notification('LBRY Download Complete', {
body: fileInfo.metadata.stream.metadata.title,
@@ -58,7 +60,9 @@ export function doUpdateLoadStatus(uri, outpoint) {
},
});
- NativeModules.LbryDownloadManager.updateDownload(uri, fileInfo.file_name, progress, writtenBytes, totalBytes);
+ if (NativeModules.LbryDownloadManager) {
+ NativeModules.LbryDownloadManager.updateDownload(uri, fileInfo.file_name, progress, writtenBytes, totalBytes);
+ }
setTimeout(() => {
dispatch(doUpdateLoadStatus(uri, outpoint));
@@ -90,7 +94,9 @@ export function doStartDownload(uri, outpoint) {
},
});
- NativeModules.LbryDownloadManager.startDownload(uri, fileInfo.file_name);
+ if (NativeModules.LbryDownloadManager) {
+ NativeModules.LbryDownloadManager.startDownload(uri, fileInfo.file_name);
+ }
dispatch(doUpdateLoadStatus(uri, outpoint));
});
@@ -114,7 +120,9 @@ export function doStopDownloadingFile(uri, fileInfo) {
});
});
- NativeModules.LbryDownloadManager.stopDownload(uri, fileInfo.file_name);
+ if (NativeModules.LbryDownloadManager) {
+ NativeModules.LbryDownloadManager.stopDownload(uri, fileInfo.file_name);
+ }
// Should also delete the file after the user stops downloading
dispatch(doDeleteFile(fileInfo.outpoint, uri));
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/templates/AndroidManifest.tmpl.xml b/p4a/pythonforandroid/bootstraps/lbry/build/templates/AndroidManifest.tmpl.xml
index 45e132e..0b93dc0 100644
--- a/p4a/pythonforandroid/bootstraps/lbry/build/templates/AndroidManifest.tmpl.xml
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/templates/AndroidManifest.tmpl.xml
@@ -72,8 +72,15 @@
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:configChanges="keyboardHidden|orientation{% if args.min_sdk_version >= 13 %}|screenSize{% endif %}"
android:screenOrientation="{{ args.orientation }}"
+ android:launchMode="singleInstance"
>
-
+
+
+
+
+
+
+
{% if args.launcher %}
diff --git a/src/main/java/io/lbry/browser/MainActivity.java b/src/main/java/io/lbry/browser/MainActivity.java
index c968421..853056a 100644
--- a/src/main/java/io/lbry/browser/MainActivity.java
+++ b/src/main/java/io/lbry/browser/MainActivity.java
@@ -31,7 +31,7 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
private static final int OVERLAY_PERMISSION_REQ_CODE = 101;
private static final int STORAGE_PERMISSION_REQ_CODE = 201;
-
+
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
@@ -43,7 +43,11 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
* onResume method.
*/
private boolean serviceRunning;
-
+
+ protected String getMainComponentName() {
+ return "LBRYApp";
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
@@ -174,6 +178,14 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
super.onBackPressed();
}
}
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ if (mReactInstanceManager != null) {
+ mReactInstanceManager.onNewIntent(intent);
+ }
+ super.onNewIntent(intent);
+ }
private boolean isServiceRunning(Class> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
diff --git a/src/main/java/io/lbry/browser/reactmodules/DownloadManagerModule.java b/src/main/java/io/lbry/browser/reactmodules/DownloadManagerModule.java
index ecd97c9..e9563d0 100644
--- a/src/main/java/io/lbry/browser/reactmodules/DownloadManagerModule.java
+++ b/src/main/java/io/lbry/browser/reactmodules/DownloadManagerModule.java
@@ -4,6 +4,7 @@ import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
@@ -27,7 +28,7 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
private HashMap downloadIdNotificationIdMap = new HashMap();
- private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
+ private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#");
private static final int MAX_PROGRESS = 100;
@@ -74,8 +75,8 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
}
}
- private PendingIntent getLaunchPendingIntent() {
- Intent launchIntent = new Intent(context, MainActivity.class);
+ private PendingIntent getLaunchPendingIntent(String uri) {
+ Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0, launchIntent, 0);
return intent;
@@ -87,7 +88,8 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
- builder.setContentIntent(getLaunchPendingIntent())
+ // The file URI is used as the unique ID
+ builder.setContentIntent(getLaunchPendingIntent(id))
.setContentTitle(String.format("Downloading %s...", fileName))
.setGroup(GROUP_DOWNLOADS)
.setPriority(NotificationCompat.PRIORITY_LOW)
@@ -115,14 +117,18 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
createNotificationGroup();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
NotificationCompat.Builder builder = builders.get(notificationId);
- builder.setContentIntent(getLaunchPendingIntent())
+ builder.setContentIntent(getLaunchPendingIntent(id))
.setContentText(String.format("%.0f%% (%s / %s)", progress, formatBytes(writtenBytes), formatBytes(totalBytes)))
.setGroup(GROUP_DOWNLOADS)
.setProgress(MAX_PROGRESS, new Double(progress).intValue(), false);
notificationManager.notify(notificationId, builder.build());
if (progress == MAX_PROGRESS) {
- builder.setContentTitle(String.format("Downloaded %s.", fileName));
+ builder.setContentTitle(String.format("Downloaded %s", fileName))
+ .setContentText(String.format("%s", formatBytes(totalBytes)))
+ .setProgress(0, 0, false);
+ notificationManager.notify(notificationId, builder.build());
+
downloadIdNotificationIdMap.remove(id);
builders.remove(notificationId);
}