Handle lbry:// url scheme, and download notification fixes. (#139)
This commit is contained in:
parent
4fbf90654e
commit
7d2e4c1e8c
6 changed files with 76 additions and 15 deletions
|
@ -20,6 +20,7 @@ import {
|
||||||
AppState,
|
AppState,
|
||||||
AsyncStorage,
|
AsyncStorage,
|
||||||
BackHandler,
|
BackHandler,
|
||||||
|
Linking,
|
||||||
NativeModules,
|
NativeModules,
|
||||||
TextInput,
|
TextInput,
|
||||||
ToastAndroid
|
ToastAndroid
|
||||||
|
@ -109,7 +110,7 @@ class AppWithNavigationState extends React.Component {
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
AppState.addEventListener('change', this._handleAppStateChange);
|
AppState.addEventListener('change', this._handleAppStateChange);
|
||||||
BackHandler.addEventListener('hardwareBackPress', function() {
|
BackHandler.addEventListener('hardwareBackPress', function() {
|
||||||
const { dispatch, navigation, nav } = this.props;
|
const { dispatch, nav } = this.props;
|
||||||
// There should be a better way to check this
|
// There should be a better way to check this
|
||||||
if (nav.routes.length > 0) {
|
if (nav.routes.length > 0) {
|
||||||
const subRoutes = nav.routes[0].routes[0].routes;
|
const subRoutes = nav.routes[0].routes[0].routes;
|
||||||
|
@ -130,9 +131,14 @@ class AppWithNavigationState extends React.Component {
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
Linking.addEventListener('url', this._handleUrl);
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
AppState.removeEventListener('change', this._handleAppStateChange);
|
AppState.removeEventListener('change', this._handleAppStateChange);
|
||||||
BackHandler.removeEventListener('hardwareBackPress');
|
BackHandler.removeEventListener('hardwareBackPress');
|
||||||
|
Linking.removeEventListener('url', this._handleUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUpdate(nextProps) {
|
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() {
|
render() {
|
||||||
const { dispatch, nav } = this.props;
|
const { dispatch, nav } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Lbry } from 'lbry-redux';
|
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 { NavigationActions } from 'react-navigation';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import splashStyle from '../../styles/splash';
|
import splashStyle from '../../styles/splash';
|
||||||
|
@ -16,6 +16,7 @@ class SplashScreen extends React.PureComponent {
|
||||||
message: 'Connecting',
|
message: 'Connecting',
|
||||||
isRunning: false,
|
isRunning: false,
|
||||||
isLagging: false,
|
isLagging: false,
|
||||||
|
launchUrl: null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +52,10 @@ class SplashScreen extends React.PureComponent {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
navigation.dispatch(resetAction);
|
navigation.dispatch(resetAction);
|
||||||
|
|
||||||
|
if (this.state.launchUrl) {
|
||||||
|
navigation.navigate('File', { uri: this.state.launchUrl });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -79,6 +84,12 @@ class SplashScreen extends React.PureComponent {
|
||||||
NativeModules.Mixpanel.track('App Launch', null);
|
NativeModules.Mixpanel.track('App Launch', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linking.getInitialURL().then((url) => {
|
||||||
|
if (url) {
|
||||||
|
this.setState({ launchUrl: url });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Lbry
|
Lbry
|
||||||
.connect()
|
.connect()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -34,7 +34,9 @@ export function doUpdateLoadStatus(uri, outpoint) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (NativeModules.LbryDownloadManager) {
|
||||||
NativeModules.LbryDownloadManager.updateDownload(uri, fileInfo.file_name, 100, writtenBytes, totalBytes);
|
NativeModules.LbryDownloadManager.updateDownload(uri, fileInfo.file_name, 100, writtenBytes, totalBytes);
|
||||||
|
}
|
||||||
|
|
||||||
/*const notif = new window.Notification('LBRY Download Complete', {
|
/*const notif = new window.Notification('LBRY Download Complete', {
|
||||||
body: fileInfo.metadata.stream.metadata.title,
|
body: fileInfo.metadata.stream.metadata.title,
|
||||||
|
@ -58,7 +60,9 @@ export function doUpdateLoadStatus(uri, outpoint) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (NativeModules.LbryDownloadManager) {
|
||||||
NativeModules.LbryDownloadManager.updateDownload(uri, fileInfo.file_name, progress, writtenBytes, totalBytes);
|
NativeModules.LbryDownloadManager.updateDownload(uri, fileInfo.file_name, progress, writtenBytes, totalBytes);
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch(doUpdateLoadStatus(uri, outpoint));
|
dispatch(doUpdateLoadStatus(uri, outpoint));
|
||||||
|
@ -90,7 +94,9 @@ export function doStartDownload(uri, outpoint) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (NativeModules.LbryDownloadManager) {
|
||||||
NativeModules.LbryDownloadManager.startDownload(uri, fileInfo.file_name);
|
NativeModules.LbryDownloadManager.startDownload(uri, fileInfo.file_name);
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(doUpdateLoadStatus(uri, outpoint));
|
dispatch(doUpdateLoadStatus(uri, outpoint));
|
||||||
});
|
});
|
||||||
|
@ -114,7 +120,9 @@ export function doStopDownloadingFile(uri, fileInfo) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (NativeModules.LbryDownloadManager) {
|
||||||
NativeModules.LbryDownloadManager.stopDownload(uri, fileInfo.file_name);
|
NativeModules.LbryDownloadManager.stopDownload(uri, fileInfo.file_name);
|
||||||
|
}
|
||||||
|
|
||||||
// Should also delete the file after the user stops downloading
|
// Should also delete the file after the user stops downloading
|
||||||
dispatch(doDeleteFile(fileInfo.outpoint, uri));
|
dispatch(doDeleteFile(fileInfo.outpoint, uri));
|
||||||
|
|
|
@ -72,8 +72,15 @@
|
||||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
|
||||||
android:configChanges="keyboardHidden|orientation{% if args.min_sdk_version >= 13 %}|screenSize{% endif %}"
|
android:configChanges="keyboardHidden|orientation{% if args.min_sdk_version >= 13 %}|screenSize{% endif %}"
|
||||||
android:screenOrientation="{{ args.orientation }}"
|
android:screenOrientation="{{ args.orientation }}"
|
||||||
|
android:launchMode="singleInstance"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data android:scheme="lbry" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
{% if args.launcher %}
|
{% if args.launcher %}
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|
|
@ -44,6 +44,10 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
|
||||||
*/
|
*/
|
||||||
private boolean serviceRunning;
|
private boolean serviceRunning;
|
||||||
|
|
||||||
|
protected String getMainComponentName() {
|
||||||
|
return "LBRYApp";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
@ -175,6 +179,14 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewIntent(Intent intent) {
|
||||||
|
if (mReactInstanceManager != null) {
|
||||||
|
mReactInstanceManager.onNewIntent(intent);
|
||||||
|
}
|
||||||
|
super.onNewIntent(intent);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isServiceRunning(Class<?> serviceClass) {
|
private boolean isServiceRunning(Class<?> serviceClass) {
|
||||||
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
for (ActivityManager.RunningServiceInfo serviceInfo : manager.getRunningServices(Integer.MAX_VALUE)) {
|
for (ActivityManager.RunningServiceInfo serviceInfo : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.app.PendingIntent;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.NotificationManagerCompat;
|
import android.support.v4.app.NotificationManagerCompat;
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
private HashMap<String, Integer> downloadIdNotificationIdMap = new HashMap<String, Integer>();
|
private HashMap<String, Integer> downloadIdNotificationIdMap = new HashMap<String, Integer>();
|
||||||
|
|
||||||
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
|
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#");
|
||||||
|
|
||||||
private static final int MAX_PROGRESS = 100;
|
private static final int MAX_PROGRESS = 100;
|
||||||
|
|
||||||
|
@ -74,8 +75,8 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PendingIntent getLaunchPendingIntent() {
|
private PendingIntent getLaunchPendingIntent(String uri) {
|
||||||
Intent launchIntent = new Intent(context, MainActivity.class);
|
Intent launchIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
||||||
launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
launchIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
PendingIntent intent = PendingIntent.getActivity(context, 0, launchIntent, 0);
|
PendingIntent intent = PendingIntent.getActivity(context, 0, launchIntent, 0);
|
||||||
return intent;
|
return intent;
|
||||||
|
@ -87,7 +88,8 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(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))
|
.setContentTitle(String.format("Downloading %s...", fileName))
|
||||||
.setGroup(GROUP_DOWNLOADS)
|
.setGroup(GROUP_DOWNLOADS)
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
|
@ -115,14 +117,18 @@ public class DownloadManagerModule extends ReactContextBaseJavaModule {
|
||||||
createNotificationGroup();
|
createNotificationGroup();
|
||||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||||
NotificationCompat.Builder builder = builders.get(notificationId);
|
NotificationCompat.Builder builder = builders.get(notificationId);
|
||||||
builder.setContentIntent(getLaunchPendingIntent())
|
builder.setContentIntent(getLaunchPendingIntent(id))
|
||||||
.setContentText(String.format("%.0f%% (%s / %s)", progress, formatBytes(writtenBytes), formatBytes(totalBytes)))
|
.setContentText(String.format("%.0f%% (%s / %s)", progress, formatBytes(writtenBytes), formatBytes(totalBytes)))
|
||||||
.setGroup(GROUP_DOWNLOADS)
|
.setGroup(GROUP_DOWNLOADS)
|
||||||
.setProgress(MAX_PROGRESS, new Double(progress).intValue(), false);
|
.setProgress(MAX_PROGRESS, new Double(progress).intValue(), false);
|
||||||
notificationManager.notify(notificationId, builder.build());
|
notificationManager.notify(notificationId, builder.build());
|
||||||
|
|
||||||
if (progress == MAX_PROGRESS) {
|
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);
|
downloadIdNotificationIdMap.remove(id);
|
||||||
builders.remove(notificationId);
|
builders.remove(notificationId);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue