mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
This commit is contained in:
parent
21dbc800d5
commit
18a0ca0881
@ -77,18 +77,8 @@
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- SHARE EXTENSION -->
|
||||
<activity
|
||||
android:noHistory="true"
|
||||
android:name=".ShareActivity"
|
||||
android:configChanges="orientation"
|
||||
android:launchMode="singleTask"
|
||||
android:label="@string/app_name"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/AppTheme"
|
||||
android:exported="true">
|
||||
<!-- SHARE EXTENSION -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@ -99,8 +89,8 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="*/*" />
|
||||
</intent-filter>
|
||||
<!-- /SHARE EXTENSION -->
|
||||
</activity>
|
||||
<!-- /SHARE EXTENSION -->
|
||||
|
||||
</application>
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
package net.cozic.joplin;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
|
||||
public class ShareActivity extends ReactActivity {
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
// this is the name AppRegistry will use to launch the Share View
|
||||
return "Joplin";
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import androidx.annotation.NonNull;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.ActivityEventListener;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
@ -21,6 +22,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.io.File;
|
||||
@ -42,11 +44,14 @@ public class SharePackage implements ReactPackage {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static class ShareModule extends ReactContextBaseJavaModule implements ActivityEventListener {
|
||||
public static class ShareModule extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener {
|
||||
private boolean handledStartIntent = false;
|
||||
private Intent receivedShareIntent = null;
|
||||
|
||||
ShareModule(@NonNull ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
reactContext.addActivityEventListener(this);
|
||||
reactContext.addLifecycleEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,6 +60,14 @@ public class SharePackage implements ReactPackage {
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
if (intent == null || !(Intent.ACTION_SEND.equals(intent.getAction())
|
||||
|| Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction()))) {
|
||||
return;
|
||||
}
|
||||
receivedShareIntent = intent;
|
||||
this.getReactApplicationContext()
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit("new_share_intent", null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -77,37 +90,29 @@ public class SharePackage implements ReactPackage {
|
||||
}
|
||||
|
||||
private WritableMap processIntent() {
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
WritableMap map = Arguments.createMap();
|
||||
|
||||
if (currentActivity == null) {
|
||||
if (receivedShareIntent == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Intent intent = currentActivity.getIntent();
|
||||
|
||||
if (intent == null || !(Intent.ACTION_SEND.equals(intent.getAction())
|
||||
|| Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction()))) {
|
||||
if (receivedShareIntent.getBooleanExtra("is_processed", false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (intent.getBooleanExtra("is_processed", false)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String type = intent.getType() == null ? "" : intent.getType();
|
||||
String type = receivedShareIntent.getType() == null ? "" : receivedShareIntent.getType();
|
||||
map.putString("type", type);
|
||||
map.putString("title", getTitle(intent));
|
||||
map.putString("text", intent.getStringExtra(Intent.EXTRA_TEXT));
|
||||
map.putString("title", getTitle(receivedShareIntent));
|
||||
map.putString("text", receivedShareIntent.getStringExtra(Intent.EXTRA_TEXT));
|
||||
|
||||
WritableArray resources = Arguments.createArray();
|
||||
|
||||
if (Intent.ACTION_SEND.equals(intent.getAction())) {
|
||||
if (intent.hasExtra(Intent.EXTRA_STREAM)) {
|
||||
resources.pushMap(getFileData(intent.getParcelableExtra(Intent.EXTRA_STREAM)));
|
||||
if (Intent.ACTION_SEND.equals(receivedShareIntent.getAction())) {
|
||||
if (receivedShareIntent.hasExtra(Intent.EXTRA_STREAM)) {
|
||||
resources.pushMap(getFileData(receivedShareIntent.getParcelableExtra(Intent.EXTRA_STREAM)));
|
||||
}
|
||||
} else if (Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) {
|
||||
ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
} else if (Intent.ACTION_SEND_MULTIPLE.equals(receivedShareIntent.getAction())) {
|
||||
ArrayList<Uri> imageUris = receivedShareIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
if (imageUris != null) {
|
||||
for (Uri uri : imageUris) {
|
||||
resources.pushMap(getFileData(uri));
|
||||
@ -116,7 +121,7 @@ public class SharePackage implements ReactPackage {
|
||||
}
|
||||
|
||||
map.putArray("resources", resources);
|
||||
intent.putExtra("is_processed", true);
|
||||
receivedShareIntent.putExtra("is_processed", true);
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -185,5 +190,36 @@ public class SharePackage implements ReactPackage {
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void addListener(String eventName) {
|
||||
// Set up any upstream listeners or background tasks as necessary
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void removeListeners(Integer count) {
|
||||
// Remove upstream listeners, stop unnecessary background tasks
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
if (this.getCurrentActivity() != null) {
|
||||
Intent intent = this.getCurrentActivity().getIntent();
|
||||
if (this.handledStartIntent) {
|
||||
// sometimes onHostResume is fired after onNewIntent
|
||||
// and we only care about the activity intent when the first time app opens
|
||||
return;
|
||||
}
|
||||
this.handledStartIntent = true;
|
||||
this.onNewIntent(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,15 +139,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
}
|
||||
|
||||
if (this.state.fromShare) {
|
||||
// effectively the same as NAV_BACK but NAV_BACK causes undesired behaviour in this case:
|
||||
// - share to Joplin from some other app
|
||||
// - open Joplin and open any note
|
||||
// - go back -- with NAV_BACK this causes the app to exit rather than just showing notes
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Notes',
|
||||
folderId: this.state.note.parent_id,
|
||||
});
|
||||
ShareExtension.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -458,10 +450,6 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
shared.uninstallResourceHandling(this.refreshResource);
|
||||
|
||||
if (this.state.fromShare) {
|
||||
ShareExtension.close();
|
||||
}
|
||||
|
||||
this.saveActionQueue(this.state.note.id).processAllNow();
|
||||
|
||||
// It cannot theoretically be undefined, since componentDidMount should always be called before
|
||||
|
@ -735,6 +735,15 @@ class AppComponent extends React.Component {
|
||||
}
|
||||
};
|
||||
|
||||
this.handleNewShare_ = () => {
|
||||
// look at this.handleOpenURL_ comment
|
||||
if (this.props.biometricsDone) {
|
||||
void this.handleShareData();
|
||||
}
|
||||
};
|
||||
|
||||
this.unsubscribeNewShareListener_ = ShareExtension.addShareListener(this.handleNewShare_);
|
||||
|
||||
this.handleScreenWidthChange_ = this.handleScreenWidthChange_.bind(this);
|
||||
}
|
||||
|
||||
@ -840,6 +849,11 @@ class AppComponent extends React.Component {
|
||||
}
|
||||
|
||||
if (this.unsubscribeNetInfoHandler_) this.unsubscribeNetInfoHandler_();
|
||||
|
||||
if (this.unsubscribeNewShareListener_) {
|
||||
this.unsubscribeNewShareListener_();
|
||||
this.unsubscribeNewShareListener_ = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: any) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { NativeEventEmitter } from 'react-native';
|
||||
|
||||
const { NativeModules, Platform } = require('react-native');
|
||||
|
||||
export interface SharedData {
|
||||
@ -6,16 +8,25 @@ export interface SharedData {
|
||||
resources?: string[];
|
||||
}
|
||||
|
||||
let eventEmitter: NativeEventEmitter | undefined;
|
||||
|
||||
const ShareExtension = (NativeModules.ShareExtension) ?
|
||||
{
|
||||
data: () => NativeModules.ShareExtension.data(),
|
||||
close: () => NativeModules.ShareExtension.close(),
|
||||
shareURL: (Platform.OS === 'ios') ? NativeModules.ShareExtension.getConstants().SHARE_EXTENSION_SHARE_URL : '',
|
||||
addShareListener: (Platform.OS === 'android') ? ((handler: (event: any)=> void) => {
|
||||
if (!eventEmitter) {
|
||||
eventEmitter = new NativeEventEmitter(NativeModules.ShareExtension);
|
||||
}
|
||||
return eventEmitter.addListener('new_share_intent', handler).remove;
|
||||
}) : (() => {}),
|
||||
} :
|
||||
{
|
||||
data: () => {},
|
||||
close: () => {},
|
||||
shareURL: '',
|
||||
addShareListener: () => {},
|
||||
};
|
||||
|
||||
export default ShareExtension;
|
||||
|
Loading…
Reference in New Issue
Block a user