diff --git a/.eslintignore b/.eslintignore index 5901377ac..e8e44d279 100644 --- a/.eslintignore +++ b/.eslintignore @@ -627,6 +627,7 @@ packages/lib/import-enex.js packages/lib/initLib.js packages/lib/locale.test.js packages/lib/locale.js +packages/lib/makeDiscourseDebugUrl.js packages/lib/markdownUtils.test.js packages/lib/markdownUtils.js packages/lib/markdownUtils2.test.js diff --git a/.gitignore b/.gitignore index 79ac880fc..adce23da0 100644 --- a/.gitignore +++ b/.gitignore @@ -609,6 +609,7 @@ packages/lib/import-enex.js packages/lib/initLib.js packages/lib/locale.test.js packages/lib/locale.js +packages/lib/makeDiscourseDebugUrl.js packages/lib/markdownUtils.test.js packages/lib/markdownUtils.js packages/lib/markdownUtils2.test.js diff --git a/packages/app-desktop/bridge.ts b/packages/app-desktop/bridge.ts index 4c0a2adf7..8ac27ae8f 100644 --- a/packages/app-desktop/bridge.ts +++ b/packages/app-desktop/bridge.ts @@ -184,11 +184,16 @@ export class Bridge { return dialog.showMessageBoxSync(window, options); } - public showErrorMessageBox(message: string) { + public showErrorMessageBox(message: string, options: any = null) { + options = { + buttons: [_('OK')], + ...options, + }; + return this.showMessageBox_(this.window(), { type: 'error', message: message, - buttons: [_('OK')], + buttons: options.buttons, }); } diff --git a/packages/app-desktop/gui/MenuBar.tsx b/packages/app-desktop/gui/MenuBar.tsx index 129a61b90..e49df45d3 100644 --- a/packages/app-desktop/gui/MenuBar.tsx +++ b/packages/app-desktop/gui/MenuBar.tsx @@ -9,6 +9,7 @@ import { PluginStates, utils as pluginUtils } from '@joplin/lib/services/plugins import shim from '@joplin/lib/shim'; import Setting from '@joplin/lib/models/Setting'; import versionInfo from '@joplin/lib/versionInfo'; +import makeDiscourseDebugUrl from '@joplin/lib/makeDiscourseDebugUrl'; import { ImportModule } from '@joplin/lib/services/interop/Module'; import InteropServiceHelper from '../InteropServiceHelper'; import { _ } from '@joplin/lib/locale'; @@ -319,11 +320,27 @@ function useMenu(props: Props) { void CommandService.instance().execute('hideModalMessage'); if (errors.length) { - bridge().showErrorMessageBox('There was some errors importing the notes. Please check the console for more details.'); + const response = bridge().showErrorMessageBox('There was some errors importing the notes - check the console for more details.\n\nPlease consider sending a bug report to the forum!', { + buttons: [_('Close'), _('Send bug report')], + }); + props.dispatch({ type: 'NOTE_DEVTOOLS_SET', value: true }); + + if (response === 1) { + const url = makeDiscourseDebugUrl( + `Error importing notes from format: ${module.format}`, + `- Input format: ${module.format}\n- Output format: ${module.outputFormat}`, + errors, + packageInfo, + PluginService.instance(), + props.pluginSettings, + ); + + void bridge().openExternal(url); + } } // eslint-disable-next-line @seiyab/react-hooks/exhaustive-deps -- Old code before rule was applied - }, [props.selectedFolderId]); + }, [props.selectedFolderId, props.pluginSettings]); const onMenuItemClickRef = useRef(null); onMenuItemClickRef.current = onMenuItemClick; diff --git a/packages/lib/makeDiscourseDebugUrl.ts b/packages/lib/makeDiscourseDebugUrl.ts new file mode 100644 index 000000000..002b314a1 --- /dev/null +++ b/packages/lib/makeDiscourseDebugUrl.ts @@ -0,0 +1,25 @@ +import { PluginSettings } from './services/plugins/PluginService'; +import type PluginService from './services/plugins/PluginService'; +import versionInfo from './versionInfo'; + +const renderErrorBlock = (errors: any[]): string => { + if (!errors.length) return ''; + return `\`\`\`\n${errors.map(e => typeof e === 'string' ? e.trim() : e.message.trim())}\n\`\`\``; +}; + +export default (title: string, body: string, errors: any[], packageInfo: any, pluginService: PluginService, pluginSettings: PluginSettings) => { + const v = versionInfo(packageInfo, pluginService.enabledPlugins(pluginSettings)); + + const errorBlock = renderErrorBlock(errors); + + const query: Record = { + title, + body: `# About\n\n${v.body.trim()}\n\n# Body\n\n${body}${errorBlock ? `\n\n# Errors\n\n${errorBlock}` : ''}`, + category: 'support', + }; + + const queryString = Object.keys(query).map(k => `${k}=${encodeURIComponent(query[k])}`).join('&'); + + const url = `https://discourse.joplinapp.org/new-topic?${queryString}`; + return url; +};