mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
parent
949c92f6d6
commit
33ad0dce15
@ -89,6 +89,7 @@ ElectronClient/gui/NoteToolbar/NoteToolbar.js
|
|||||||
ElectronClient/gui/ResourceScreen.js
|
ElectronClient/gui/ResourceScreen.js
|
||||||
ElectronClient/gui/ShareNoteDialog.js
|
ElectronClient/gui/ShareNoteDialog.js
|
||||||
ReactNativeClient/lib/AsyncActionQueue.js
|
ReactNativeClient/lib/AsyncActionQueue.js
|
||||||
|
ReactNativeClient/lib/checkPermissions.js
|
||||||
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
||||||
ReactNativeClient/lib/hooks/usePrevious.js
|
ReactNativeClient/lib/hooks/usePrevious.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
||||||
@ -96,6 +97,8 @@ ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
|||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
|
||||||
ReactNativeClient/lib/JoplinServerApi.js
|
ReactNativeClient/lib/JoplinServerApi.js
|
||||||
|
ReactNativeClient/lib/ShareExtension.js
|
||||||
|
ReactNativeClient/lib/shareHandler.js
|
||||||
ReactNativeClient/lib/services/keychain/KeychainService.js
|
ReactNativeClient/lib/services/keychain/KeychainService.js
|
||||||
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.dummy.js
|
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.dummy.js
|
||||||
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.mobile.js
|
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.mobile.js
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -79,6 +79,7 @@ ElectronClient/gui/NoteToolbar/NoteToolbar.js
|
|||||||
ElectronClient/gui/ResourceScreen.js
|
ElectronClient/gui/ResourceScreen.js
|
||||||
ElectronClient/gui/ShareNoteDialog.js
|
ElectronClient/gui/ShareNoteDialog.js
|
||||||
ReactNativeClient/lib/AsyncActionQueue.js
|
ReactNativeClient/lib/AsyncActionQueue.js
|
||||||
|
ReactNativeClient/lib/checkPermissions.js
|
||||||
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
ReactNativeClient/lib/hooks/useImperativeHandlerDebugger.js
|
||||||
ReactNativeClient/lib/hooks/usePrevious.js
|
ReactNativeClient/lib/hooks/usePrevious.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
|
||||||
@ -86,6 +87,8 @@ ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
|
|||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
|
||||||
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
|
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
|
||||||
ReactNativeClient/lib/JoplinServerApi.js
|
ReactNativeClient/lib/JoplinServerApi.js
|
||||||
|
ReactNativeClient/lib/ShareExtension.js
|
||||||
|
ReactNativeClient/lib/shareHandler.js
|
||||||
ReactNativeClient/lib/services/keychain/KeychainService.js
|
ReactNativeClient/lib/services/keychain/KeychainService.js
|
||||||
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.dummy.js
|
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.dummy.js
|
||||||
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.mobile.js
|
ReactNativeClient/lib/services/keychain/KeychainServiceDriver.mobile.js
|
||||||
|
@ -101,11 +101,17 @@
|
|||||||
android:configChanges="orientation"
|
android:configChanges="orientation"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/AppTheme" >
|
android:excludeFromRecents="true"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<data android:mimeType="text/plain" />
|
<data android:mimeType="*/*" />
|
||||||
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="*/*" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
@ -2,23 +2,21 @@ package net.cozic.joplin;
|
|||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.database.CursorWindow;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
import com.facebook.react.PackageList;
|
import com.facebook.react.PackageList;
|
||||||
import com.facebook.react.ReactApplication;
|
import com.facebook.react.ReactApplication;
|
||||||
import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage;
|
|
||||||
import com.facebook.react.ReactInstanceManager;
|
|
||||||
import com.facebook.react.ReactNativeHost;
|
import com.facebook.react.ReactNativeHost;
|
||||||
import com.facebook.react.ReactPackage;
|
import com.facebook.react.ReactPackage;
|
||||||
import com.facebook.react.shell.MainReactPackage;
|
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
|
|
||||||
|
import net.cozic.joplin.share.SharePackage;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
// import com.alinz.parkerdan.shareextension.SharePackage;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import android.database.CursorWindow;
|
|
||||||
import com.reactNativeQuickActions.AppShortcutsPackage;
|
|
||||||
|
|
||||||
public class MainApplication extends Application implements ReactApplication {
|
public class MainApplication extends Application implements ReactApplication {
|
||||||
|
|
||||||
@ -31,10 +29,9 @@ public class MainApplication extends Application implements ReactApplication {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<ReactPackage> getPackages() {
|
protected List<ReactPackage> getPackages() {
|
||||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
|
||||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||||
// packages.add(new MyReactNativePackage());
|
packages.add(new SharePackage());
|
||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package net.cozic.joplin.share;
|
package net.cozic.joplin.share;
|
||||||
|
|
||||||
|
|
||||||
// import ReactActivity
|
|
||||||
import com.facebook.react.ReactActivity;
|
import com.facebook.react.ReactActivity;
|
||||||
|
|
||||||
|
|
||||||
public class ShareActivity extends ReactActivity {
|
public class ShareActivity extends ReactActivity {
|
||||||
@Override
|
@Override
|
||||||
protected String getMainComponentName() {
|
protected String getMainComponentName() {
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
package net.cozic.joplin.share;
|
|
||||||
// import build config
|
|
||||||
import net.cozic.joplin.BuildConfig;
|
|
||||||
|
|
||||||
// import com.alinz.parkerdan.shareextension.SharePackage;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
|
|
||||||
import com.facebook.react.shell.MainReactPackage;
|
|
||||||
import com.facebook.react.ReactNativeHost;
|
|
||||||
import com.facebook.react.ReactApplication;
|
|
||||||
import com.facebook.react.ReactPackage;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
public class ShareApplication extends Application implements ReactApplication {
|
|
||||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
|
|
||||||
@Override
|
|
||||||
public boolean getUseDeveloperSupport() {
|
|
||||||
return BuildConfig.DEBUG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<ReactPackage> getPackages() {
|
|
||||||
return Arrays.<ReactPackage>asList(
|
|
||||||
new MainReactPackage()
|
|
||||||
// new SharePackage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReactNativeHost getReactNativeHost() {
|
|
||||||
return mReactNativeHost;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,184 @@
|
|||||||
|
package net.cozic.joplin.share;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.provider.OpenableColumns;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.webkit.MimeTypeMap;
|
||||||
|
|
||||||
|
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.NativeModule;
|
||||||
|
import com.facebook.react.bridge.Promise;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
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.uimanager.ViewManager;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SharePackage implements ReactPackage {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
||||||
|
return Collections.singletonList(new ShareModule(reactContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ShareModule extends ReactContextBaseJavaModule implements ActivityEventListener {
|
||||||
|
|
||||||
|
ShareModule(@NonNull ReactApplicationContext reactContext) {
|
||||||
|
super(reactContext);
|
||||||
|
reactContext.addActivityEventListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNewIntent(Intent intent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ShareExtension";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void close() {
|
||||||
|
Activity currentActivity = getCurrentActivity();
|
||||||
|
if (currentActivity != null) {
|
||||||
|
currentActivity.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void data(Promise promise) {
|
||||||
|
promise.resolve(processIntent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private WritableMap processIntent() {
|
||||||
|
Activity currentActivity = getCurrentActivity();
|
||||||
|
WritableMap map = Arguments.createMap();
|
||||||
|
|
||||||
|
if (currentActivity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Intent intent = currentActivity.getIntent();
|
||||||
|
|
||||||
|
if (intent == null || !(Intent.ACTION_SEND.equals(intent.getAction())
|
||||||
|
|| Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction()))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = intent.getType() == null ? "" : intent.getType();
|
||||||
|
map.putString("type", type);
|
||||||
|
map.putString("title", getTitle(intent));
|
||||||
|
map.putString("text", intent.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)));
|
||||||
|
}
|
||||||
|
} else if (Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) {
|
||||||
|
ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||||
|
if (imageUris != null) {
|
||||||
|
for (Uri uri : imageUris) {
|
||||||
|
resources.pushMap(getFileData(uri));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map.putArray("resources", resources);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTitle(Intent intent) {
|
||||||
|
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
|
||||||
|
return intent.getStringExtra(Intent.EXTRA_SUBJECT);
|
||||||
|
} else if (intent.hasExtra(Intent.EXTRA_TITLE)) {
|
||||||
|
return intent.getStringExtra(Intent.EXTRA_TITLE);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private WritableMap getFileData(Uri uri) {
|
||||||
|
Log.d("joplin", "getFileData: " + uri);
|
||||||
|
|
||||||
|
WritableMap imageData = Arguments.createMap();
|
||||||
|
|
||||||
|
ContentResolver contentResolver = getCurrentActivity().getContentResolver();
|
||||||
|
String mimeType = contentResolver.getType(uri);
|
||||||
|
String name = getFileName(uri, contentResolver);
|
||||||
|
|
||||||
|
if (mimeType == null || mimeType.equals("image/*")) {
|
||||||
|
String extension = getFileExtension(name);
|
||||||
|
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
imageData.putString("uri", uri.toString());
|
||||||
|
imageData.putString("name", name);
|
||||||
|
imageData.putString("mimeType", mimeType);
|
||||||
|
return imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFileName(Uri uri, ContentResolver contentResolver) {
|
||||||
|
if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
|
||||||
|
File file = new File(uri.getPath());
|
||||||
|
return file.getName();
|
||||||
|
} else if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
|
||||||
|
String name = null;
|
||||||
|
Cursor cursor = contentResolver.query(uri, null, null, null, null);
|
||||||
|
if (cursor != null) {
|
||||||
|
try {
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
||||||
|
name = cursor.getString(nameIndex);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
} else {
|
||||||
|
Log.w("joplin", "Unknown URI scheme: " + uri.getScheme());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFileExtension(String file) {
|
||||||
|
if (file == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String ext = null;
|
||||||
|
int i = file.lastIndexOf('.');
|
||||||
|
if (i > 0) {
|
||||||
|
ext = file.substring(i + 1);
|
||||||
|
}
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
ReactNativeClient/lib/ShareExtension.ts
Normal file
19
ReactNativeClient/lib/ShareExtension.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const { NativeModules, Platform } = require('react-native');
|
||||||
|
|
||||||
|
export interface SharedData {
|
||||||
|
title?: string,
|
||||||
|
text?: string,
|
||||||
|
resources?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const ShareExtension = (Platform.OS === 'android' && NativeModules.ShareExtension) ?
|
||||||
|
{
|
||||||
|
data: () => NativeModules.ShareExtension.data(),
|
||||||
|
close: () => NativeModules.ShareExtension.close(),
|
||||||
|
} :
|
||||||
|
{
|
||||||
|
data: () => {},
|
||||||
|
close: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShareExtension;
|
9
ReactNativeClient/lib/checkPermissions.ts
Normal file
9
ReactNativeClient/lib/checkPermissions.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const { PermissionsAndroid } = require('react-native');
|
||||||
|
|
||||||
|
export default async (permissions: string) => {
|
||||||
|
let result = await PermissionsAndroid.check(permissions);
|
||||||
|
if (result !== PermissionsAndroid.RESULTS.GRANTED) {
|
||||||
|
result = await PermissionsAndroid.request(permissions);
|
||||||
|
}
|
||||||
|
return result === PermissionsAndroid.RESULTS.GRANTED;
|
||||||
|
};
|
@ -36,7 +36,7 @@ const ImageResizer = require('react-native-image-resizer').default;
|
|||||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
const shared = require('lib/components/shared/note-screen-shared.js');
|
||||||
const ImagePicker = require('react-native-image-picker');
|
const ImagePicker = require('react-native-image-picker');
|
||||||
const { SelectDateTimeDialog } = require('lib/components/select-date-time-dialog.js');
|
const { SelectDateTimeDialog } = require('lib/components/select-date-time-dialog.js');
|
||||||
// const ShareExtension = require('react-native-share-extension').default;
|
const ShareExtension = require('lib/ShareExtension.js').default;
|
||||||
const CameraView = require('lib/components/CameraView');
|
const CameraView = require('lib/components/CameraView');
|
||||||
const SearchEngine = require('lib/services/SearchEngine');
|
const SearchEngine = require('lib/services/SearchEngine');
|
||||||
const urlUtils = require('lib/urlUtils');
|
const urlUtils = require('lib/urlUtils');
|
||||||
@ -123,6 +123,19 @@ class NoteScreenComponent extends BaseScreenComponent {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -333,9 +346,9 @@ class NoteScreenComponent extends BaseScreenComponent {
|
|||||||
|
|
||||||
shared.uninstallResourceHandling(this.refreshResource);
|
shared.uninstallResourceHandling(this.refreshResource);
|
||||||
|
|
||||||
// if (Platform.OS !== 'ios' && this.state.fromShare) {
|
if (this.state.fromShare) {
|
||||||
// ShareExtension.close();
|
ShareExtension.close();
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
title_changeText(text) {
|
title_changeText(text) {
|
||||||
@ -527,7 +540,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (mimeType == 'image/jpeg' || mimeType == 'image/jpg' || mimeType == 'image/png') {
|
if (mimeType == 'image/jpeg' || mimeType == 'image/jpg' || mimeType == 'image/png') {
|
||||||
const done = await this.resizeImage(localFilePath, targetPath, pickerResponse.mime);
|
const done = await this.resizeImage(localFilePath, targetPath, mimeType);
|
||||||
if (!done) return;
|
if (!done) return;
|
||||||
} else {
|
} else {
|
||||||
if (fileType === 'image') {
|
if (fileType === 'image') {
|
||||||
|
@ -200,8 +200,7 @@ shared.initState = async function(comp) {
|
|||||||
const note = await Note.load(comp.props.noteId);
|
const note = await Note.load(comp.props.noteId);
|
||||||
let mode = 'view';
|
let mode = 'view';
|
||||||
|
|
||||||
if (isProvisionalNote) {
|
if (isProvisionalNote && !comp.props.sharedData) {
|
||||||
// note = comp.props.itemType == 'todo' ? Note.newTodo(comp.props.folderId) : Note.new(comp.props.folderId);
|
|
||||||
mode = 'edit';
|
mode = 'edit';
|
||||||
comp.scheduleFocusUpdate();
|
comp.scheduleFocusUpdate();
|
||||||
}
|
}
|
||||||
@ -218,8 +217,25 @@ shared.initState = async function(comp) {
|
|||||||
noteResources: await shared.attachedResources(note ? note.body : ''),
|
noteResources: await shared.attachedResources(note ? note.body : ''),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (comp.props.sharedData) {
|
if (comp.props.sharedData) {
|
||||||
this.noteComponent_change(comp, 'body', comp.props.sharedData.value);
|
if (comp.props.sharedData.title) {
|
||||||
|
this.noteComponent_change(comp, 'title', comp.props.sharedData.title);
|
||||||
|
}
|
||||||
|
if (comp.props.sharedData.text) {
|
||||||
|
this.noteComponent_change(comp, 'body', comp.props.sharedData.text);
|
||||||
|
}
|
||||||
|
if (comp.props.sharedData.resources) {
|
||||||
|
for (let i = 0; i < comp.props.sharedData.resources.length; i++) {
|
||||||
|
const resource = comp.props.sharedData.resources[i];
|
||||||
|
reg.logger().info(`about to attach resource ${JSON.stringify(resource)}`);
|
||||||
|
await comp.attachFile({
|
||||||
|
uri: resource.uri,
|
||||||
|
type: resource.mimeType,
|
||||||
|
fileName: resource.name,
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line require-atomic-updates
|
// eslint-disable-next-line require-atomic-updates
|
||||||
|
42
ReactNativeClient/lib/shareHandler.ts
Normal file
42
ReactNativeClient/lib/shareHandler.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
const Note = require('lib/models/Note.js');
|
||||||
|
const checkPermissions = require('lib/checkPermissions.js').default;
|
||||||
|
const { ToastAndroid } = require('react-native');
|
||||||
|
const { PermissionsAndroid } = require('react-native');
|
||||||
|
|
||||||
|
import ShareExtension, { SharedData } from './ShareExtension';
|
||||||
|
|
||||||
|
export default async (sharedData: SharedData, folderId: string, dispatch: Function) => {
|
||||||
|
|
||||||
|
if (!!sharedData.resources && sharedData.resources.length > 0) {
|
||||||
|
const hasPermissions = await checkPermissions(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
|
||||||
|
|
||||||
|
if (!hasPermissions) {
|
||||||
|
ToastAndroid.show('Cannot receive shared data - permission denied', ToastAndroid.SHORT);
|
||||||
|
ShareExtension.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a bit hacky, but the surest way to go to
|
||||||
|
// the needed note. We go back one screen in case there's
|
||||||
|
// already a note open - if we don't do this, the dispatch
|
||||||
|
// below will do nothing (because routeName wouldn't change)
|
||||||
|
// Then we wait a bit for the state to be set correctly, and
|
||||||
|
// finally we go to the new note.
|
||||||
|
await dispatch({ type: 'NAV_BACK' });
|
||||||
|
|
||||||
|
await dispatch({ type: 'SIDE_MENU_CLOSE' });
|
||||||
|
|
||||||
|
const newNote = await Note.save({
|
||||||
|
parent_id: folderId,
|
||||||
|
}, { provisional: true });
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
dispatch({
|
||||||
|
type: 'NAV_GO',
|
||||||
|
routeName: 'Note',
|
||||||
|
noteId: newNote.id,
|
||||||
|
sharedData: sharedData,
|
||||||
|
});
|
||||||
|
}, 5);
|
||||||
|
};
|
@ -2,7 +2,7 @@ import setUpQuickActions from './setUpQuickActions';
|
|||||||
import PluginAssetsLoader from './PluginAssetsLoader';
|
import PluginAssetsLoader from './PluginAssetsLoader';
|
||||||
|
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const { AppState, Keyboard, NativeModules, BackHandler, Platform, Animated, View, StatusBar } = require('react-native');
|
const { AppState, Keyboard, NativeModules, BackHandler, Animated, View, StatusBar } = require('react-native');
|
||||||
const SafeAreaView = require('lib/components/SafeAreaView');
|
const SafeAreaView = require('lib/components/SafeAreaView');
|
||||||
const { connect, Provider } = require('react-redux');
|
const { connect, Provider } = require('react-redux');
|
||||||
const { BackButtonService } = require('lib/services/back-button.js');
|
const { BackButtonService } = require('lib/services/back-button.js');
|
||||||
@ -57,7 +57,8 @@ const { PoorManIntervals } = require('lib/poor-man-intervals.js');
|
|||||||
const { reducer, defaultState } = require('lib/reducer.js');
|
const { reducer, defaultState } = require('lib/reducer.js');
|
||||||
const { FileApiDriverLocal } = require('lib/file-api-driver-local.js');
|
const { FileApiDriverLocal } = require('lib/file-api-driver-local.js');
|
||||||
const DropdownAlert = require('react-native-dropdownalert').default;
|
const DropdownAlert = require('react-native-dropdownalert').default;
|
||||||
// const ShareExtension = require('react-native-share-extension').default;
|
const ShareExtension = require('lib/ShareExtension.js').default;
|
||||||
|
const handleShared = require('lib/shareHandler').default;
|
||||||
const ResourceFetcher = require('lib/services/ResourceFetcher');
|
const ResourceFetcher = require('lib/services/ResourceFetcher');
|
||||||
const SearchEngine = require('lib/services/SearchEngine');
|
const SearchEngine = require('lib/services/SearchEngine');
|
||||||
const WelcomeUtils = require('lib/WelcomeUtils');
|
const WelcomeUtils = require('lib/WelcomeUtils');
|
||||||
@ -614,43 +615,6 @@ class AppComponent extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Platform.OS !== 'ios') {
|
|
||||||
// try {
|
|
||||||
// const { type, value } = await ShareExtension.data();
|
|
||||||
|
|
||||||
// // reg.logger().info('Got share data:', type, value);
|
|
||||||
|
|
||||||
// if (type != '' && this.props.selectedFolderId) {
|
|
||||||
// const newNote = await Note.save({
|
|
||||||
// title: Note.defaultTitleFromBody(value),
|
|
||||||
// body: value,
|
|
||||||
// parent_id: this.props.selectedFolderId,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // This is a bit hacky, but the surest way to go to
|
|
||||||
// // the needed note. We go back one screen in case there's
|
|
||||||
// // already a note open - if we don't do this, the dispatch
|
|
||||||
// // below will do nothing (because routeName wouldn't change)
|
|
||||||
// // Then we wait a bit for the state to be set correctly, and
|
|
||||||
// // finally we go to the new note.
|
|
||||||
// this.props.dispatch({
|
|
||||||
// type: 'NAV_BACK',
|
|
||||||
// });
|
|
||||||
|
|
||||||
// setTimeout(() => {
|
|
||||||
// this.props.dispatch({
|
|
||||||
// type: 'NAV_GO',
|
|
||||||
// routeName: 'Note',
|
|
||||||
// noteId: newNote.id,
|
|
||||||
// });
|
|
||||||
// }, 5);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// } catch (e) {
|
|
||||||
// reg.logger().error('Error in ShareExtension.data', e);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
BackButtonService.initialize(this.backButtonHandler_);
|
BackButtonService.initialize(this.backButtonHandler_);
|
||||||
|
|
||||||
AlarmService.setInAppNotificationHandler(async (alarmId) => {
|
AlarmService.setInAppNotificationHandler(async (alarmId) => {
|
||||||
@ -660,6 +624,16 @@ class AppComponent extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
AppState.addEventListener('change', this.onAppStateChange_);
|
AppState.addEventListener('change', this.onAppStateChange_);
|
||||||
|
|
||||||
|
const sharedData = await ShareExtension.data();
|
||||||
|
if (sharedData) {
|
||||||
|
reg.logger().info('Received shared data');
|
||||||
|
if (this.props.selectedFolderId) {
|
||||||
|
handleShared(sharedData, this.props.selectedFolderId, this.props.dispatch);
|
||||||
|
} else {
|
||||||
|
reg.logger.info('Cannot handle share - default folder id is not set');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
Loading…
Reference in New Issue
Block a user