Skip to content

Commit

Permalink
Desktop: Fixes #4891: Solve "Resource Id not provided" error (#4943)
Browse files Browse the repository at this point in the history
  • Loading branch information
Subhra264 authored May 13, 2021
1 parent 5f2998a commit df6f0ce
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => {
const { scrollToPercent } = useScroll({ editor, onScroll: props.onScroll });

usePluginServiceRegistration(ref);
useContextMenu(editor, props.plugins);
useContextMenu(editor, props.plugins, props.dispatch);

const dispatchDidUpdate = (editor: any) => {
if (dispatchDidUpdateIID_) shim.clearTimeout(dispatchDidUpdateIID_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ interface ContextMenuActionOptions {

const contextMenuActionOptions: ContextMenuActionOptions = { current: null };

export default function(editor: any, plugins: PluginStates) {
export default function(editor: any, plugins: PluginStates, dispatch: Function) {
useEffect(() => {
if (!editor) return () => {};

const contextMenuItems = menuItems();
const contextMenuItems = menuItems(dispatch);

function onContextMenu(_event: any, params: any) {
const element = contextMenuElement(editor, params.x, params.y);
Expand Down Expand Up @@ -110,5 +110,5 @@ export default function(editor: any, plugins: PluginStates) {
bridge().window().webContents.off('context-menu', onContextMenu);
}
};
}, [editor, plugins]);
}, [editor, plugins, dispatch]);
}
54 changes: 45 additions & 9 deletions packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ const bridge = require('electron').remote.require('./bridge').default;
const Menu = bridge().Menu;
const MenuItem = bridge().MenuItem;
import Resource from '@joplin/lib/models/Resource';
import BaseItem from '@joplin/lib/models/BaseItem';
import BaseModel from '@joplin/lib/BaseModel';
import { processPastedHtml } from './resourceHandling';
import { NoteEntity, ResourceEntity } from '@joplin/lib/services/database/types';
const fs = require('fs-extra');
const { clipboard } = require('electron');
const { toSystemSlashes } = require('@joplin/lib/path-utils');
Expand Down Expand Up @@ -53,17 +56,50 @@ function handleCopyToClipboard(options: ContextMenuOptions) {
}
}

export function menuItems(): ContextMenuItems {
export async function openItemById(itemId: string, dispatch: Function, hash: string = '') {

const item = await BaseItem.loadItemById(itemId);

if (!item) throw new Error(`No item with ID ${itemId}`);

if (item.type_ === BaseModel.TYPE_RESOURCE) {
const resource = item as ResourceEntity;
const localState = await Resource.localState(resource);
if (localState.fetch_status !== Resource.FETCH_STATUS_DONE || !!resource.encryption_blob_encrypted) {
if (localState.fetch_status === Resource.FETCH_STATUS_ERROR) {
bridge().showErrorMessageBox(`${_('There was an error downloading this attachment:')}\n\n${localState.fetch_error}`);
} else {
bridge().showErrorMessageBox(_('This attachment is not downloaded or not decrypted yet'));
}
return;
}

try {
await ResourceEditWatcher.instance().openAndWatch(resource.id);
} catch (error) {
console.error(error);
bridge().showErrorMessageBox(error.message);
}
} else if (item.type_ === BaseModel.TYPE_NOTE) {
const note = item as NoteEntity;

dispatch({
type: 'FOLDER_AND_NOTE_SELECT',
folderId: note.parent_id,
noteId: note.id,
hash,
});
} else {
throw new Error(`Unsupported item type: ${item.type_}`);
}
}

export function menuItems(dispatch: Function): ContextMenuItems {
return {
open: {
label: _('Open...'),
onAction: async (options: ContextMenuOptions) => {
try {
await ResourceEditWatcher.instance().openAndWatch(options.resourceId);
} catch (error) {
console.error(error);
bridge().showErrorMessageBox(error.message);
}
await openItemById(options.resourceId, dispatch);
},
isActive: (itemType: ContextMenuItemType) => itemType === ContextMenuItemType.Image || itemType === ContextMenuItemType.Resource,
},
Expand Down Expand Up @@ -134,10 +170,10 @@ export function menuItems(): ContextMenuItems {
};
}

export default async function contextMenu(options: ContextMenuOptions) {
export default async function contextMenu(options: ContextMenuOptions, dispatch: Function) {
const menu = new Menu();

const items = menuItems();
const items = menuItems(dispatch);

if (!('readyOnly' in options)) options.isReadOnly = true;

Expand Down
42 changes: 4 additions & 38 deletions packages/app-desktop/gui/NoteEditor/utils/useMessageHandler.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { useCallback } from 'react';
import { FormNote } from './types';
import contextMenu from './contextMenu';
import ResourceEditWatcher from '@joplin/lib/services/ResourceEditWatcher/index';
import contextMenu, { openItemById } from './contextMenu';
import { _ } from '@joplin/lib/locale';
import CommandService from '@joplin/lib/services/CommandService';
import PostMessageService from '@joplin/lib/services/PostMessageService';
import BaseItem from '@joplin/lib/models/BaseItem';
import BaseModel from '@joplin/lib/BaseModel';
import Resource from '@joplin/lib/models/Resource';
const bridge = require('electron').remote.require('./bridge').default;
const { urlDecode } = require('@joplin/lib/string-utils');
const urlUtils = require('@joplin/lib/urlUtils');
Expand Down Expand Up @@ -46,43 +42,13 @@ export default function useMessageHandler(scrollWhenReady: any, setScrollWhenRea
linkToCopy: arg0.linkToCopy || null,
htmlToCopy: '',
insertContent: () => { console.warn('insertContent() not implemented'); },
});
}, dispatch);

menu.popup(bridge().window());
} else if (msg.indexOf('joplin://') === 0) {
const resourceUrlInfo = urlUtils.parseResourceUrl(msg);
const itemId = resourceUrlInfo.itemId;
const item = await BaseItem.loadItemById(itemId);
const { itemId, hash } = urlUtils.parseResourceUrl(msg);
await openItemById(itemId, dispatch, hash);

if (!item) throw new Error(`No item with ID ${itemId}`);

if (item.type_ === BaseModel.TYPE_RESOURCE) {
const localState = await Resource.localState(item);
if (localState.fetch_status !== Resource.FETCH_STATUS_DONE || !!item.encryption_blob_encrypted) {
if (localState.fetch_status === Resource.FETCH_STATUS_ERROR) {
bridge().showErrorMessageBox(`${_('There was an error downloading this attachment:')}\n\n${localState.fetch_error}`);
} else {
bridge().showErrorMessageBox(_('This attachment is not downloaded or not decrypted yet'));
}
return;
}

try {
await ResourceEditWatcher.instance().openAndWatch(item.id);
} catch (error) {
console.error(error);
bridge().showErrorMessageBox(error.message);
}
} else if (item.type_ === BaseModel.TYPE_NOTE) {
dispatch({
type: 'FOLDER_AND_NOTE_SELECT',
folderId: item.parent_id,
noteId: item.id,
hash: resourceUrlInfo.hash,
});
} else {
throw new Error(`Unsupported item type: ${item.type_}`);
}
} else if (urlUtils.urlProtocol(msg)) {
if (msg.indexOf('file://') === 0) {
// When using the file:// protocol, openPath doesn't work (does nothing) with URL-encoded paths
Expand Down

0 comments on commit df6f0ce

Please sign in to comment.