Skip to content

Commit 8bdec4c

Browse files
committed
Desktop: Add context menu item to view OCR text of an attachment
1 parent be58fce commit 8bdec4c

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

packages/app-desktop/gui/NoteEditor/utils/contextMenu.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ import bridge from '../../../services/bridge';
55
import { ContextMenuItemType, ContextMenuOptions, ContextMenuItems, resourceInfo, textToDataUri, svgUriToPng, svgDimensions } from './contextMenuUtils';
66
const Menu = bridge().Menu;
77
const MenuItem = bridge().MenuItem;
8-
import Resource from '@joplin/lib/models/Resource';
8+
import Resource, { resourceOcrStatusToString } from '@joplin/lib/models/Resource';
99
import BaseItem from '@joplin/lib/models/BaseItem';
1010
import BaseModel, { ModelType } from '@joplin/lib/BaseModel';
1111
import { processPastedHtml } from './resourceHandling';
12-
import { NoteEntity, ResourceEntity } from '@joplin/lib/services/database/types';
12+
import { NoteEntity, ResourceEntity, ResourceOcrStatus } from '@joplin/lib/services/database/types';
1313
import { TinyMceEditorEvents } from '../NoteBody/TinyMCE/utils/types';
1414
import { itemIsReadOnlySync, ItemSlice } from '@joplin/lib/models/utils/readOnly';
1515
import Setting from '@joplin/lib/models/Setting';
1616
import ItemChange from '@joplin/lib/models/ItemChange';
1717
import { HtmlToMarkdownHandler, MarkupToHtmlHandler } from './types';
18+
import shim from '@joplin/lib/shim';
19+
import { openFileWithExternalEditor } from '@joplin/lib/services/ExternalEditWatcher/utils';
1820
const fs = require('fs-extra');
1921
const { writeFile } = require('fs-extra');
2022
const { clipboard } = require('electron');
@@ -135,6 +137,21 @@ export function menuItems(dispatch: Function, htmlToMd: HtmlToMarkdownHandler, m
135137
},
136138
isActive: (itemType: ContextMenuItemType, options: ContextMenuOptions) => !options.textToCopy && itemType === ContextMenuItemType.Image || itemType === ContextMenuItemType.Resource,
137139
},
140+
copyOcrText: {
141+
label: _('View OCR text'),
142+
onAction: async (options: ContextMenuOptions) => {
143+
const { resource } = await resourceInfo(options);
144+
145+
if (resource.ocr_status === ResourceOcrStatus.Done) {
146+
const tempFilePath = `${Setting.value('tempDir')}/${resource.id}_ocr.txt`;
147+
await shim.fsDriver().writeFile(tempFilePath, resource.ocr_text, 'utf8');
148+
await openFileWithExternalEditor(tempFilePath, bridge());
149+
} else {
150+
bridge().showInfoMessageBox(_('This attachment does not have OCR data (Status: %s)', resourceOcrStatusToString(resource.ocr_status)));
151+
}
152+
},
153+
isActive: (itemType: ContextMenuItemType, _options: ContextMenuOptions) => itemType === ContextMenuItemType.Resource,
154+
},
138155
copyPathToClipboard: {
139156
label: _('Copy path to clipboard'),
140157
onAction: async (options: ContextMenuOptions) => {

packages/lib/models/Resource.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ import ActionLogger from '../utils/ActionLogger';
2626
import isSqliteSyntaxError from '../services/database/isSqliteSyntaxError';
2727
import { internalUrl, isResourceUrl, isSupportedImageMimeType, resourceFilename, resourceFullPath, resourcePathToId, resourceRelativePath, resourceUrlToId } from './utils/resourceUtils';
2828

29+
export const resourceOcrStatusToString = (status: ResourceOcrStatus) => {
30+
const s = {
31+
[ResourceOcrStatus.Todo]: _('Idle'),
32+
[ResourceOcrStatus.Processing]: _('Processing'),
33+
[ResourceOcrStatus.Error]: _('Error'),
34+
[ResourceOcrStatus.Done]: _('Done'),
35+
};
36+
37+
return s[status];
38+
};
39+
2940
export default class Resource extends BaseItem {
3041

3142
public static IMAGE_MAX_DIMENSION = 1920;
@@ -630,4 +641,8 @@ export default class Resource extends BaseItem {
630641
return output;
631642
}
632643

644+
public static load(id: string, options: LoadOptions = null): Promise<ResourceEntity> {
645+
return super.load(id, options);
646+
}
647+
633648
}

0 commit comments

Comments
 (0)