You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-26 22:41:17 +02:00
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 ImagePicker = require('react-native-image-picker');
|
||||
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 SearchEngine = require('lib/services/SearchEngine');
|
||||
const urlUtils = require('lib/urlUtils');
|
||||
@@ -123,6 +123,19 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -333,9 +346,9 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
shared.uninstallResourceHandling(this.refreshResource);
|
||||
|
||||
// if (Platform.OS !== 'ios' && this.state.fromShare) {
|
||||
// ShareExtension.close();
|
||||
// }
|
||||
if (this.state.fromShare) {
|
||||
ShareExtension.close();
|
||||
}
|
||||
}
|
||||
|
||||
title_changeText(text) {
|
||||
@@ -527,7 +540,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
try {
|
||||
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;
|
||||
} else {
|
||||
if (fileType === 'image') {
|
||||
|
||||
@@ -200,8 +200,7 @@ shared.initState = async function(comp) {
|
||||
const note = await Note.load(comp.props.noteId);
|
||||
let mode = 'view';
|
||||
|
||||
if (isProvisionalNote) {
|
||||
// note = comp.props.itemType == 'todo' ? Note.newTodo(comp.props.folderId) : Note.new(comp.props.folderId);
|
||||
if (isProvisionalNote && !comp.props.sharedData) {
|
||||
mode = 'edit';
|
||||
comp.scheduleFocusUpdate();
|
||||
}
|
||||
@@ -218,8 +217,25 @@ shared.initState = async function(comp) {
|
||||
noteResources: await shared.attachedResources(note ? note.body : ''),
|
||||
});
|
||||
|
||||
|
||||
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
|
||||
|
||||
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);
|
||||
};
|
||||
Reference in New Issue
Block a user