import * as React from 'react'; import { connect } from 'react-redux'; import { AppState } from '../../../app.reducer'; import Setting from '@joplin/lib/models/Setting'; import BannerContent from './BannerContent'; import { _ } from '@joplin/lib/locale'; import onRichTextReadMoreLinkClick from '@joplin/lib/components/shared/NoteEditor/WarningBanner/onRichTextReadMoreLinkClick'; import onRichTextDismissLinkClick from '@joplin/lib/components/shared/NoteEditor/WarningBanner/onRichTextDismissLinkClick'; import useEditorTypeMigrationBanner from '@joplin/lib/components/shared/NoteEditor/WarningBanner/useEditorTypeMigrationBanner'; import { useMemo } from 'react'; import { PluginStates } from '@joplin/lib/services/plugins/reducer'; import PluginService from '@joplin/lib/services/plugins/PluginService'; import { NoteBodyEditorType } from '../utils/types'; interface Props { bodyEditor: NoteBodyEditorType; lockedInShare: boolean; editorMigrationVersion: number; richTextBannerDismissed: boolean; inEditorRenderingEnabled: boolean; pluginCompatibilityBannerDismissedFor: string[]; plugins: PluginStates; } const onSwitchToLegacyEditor = () => { Setting.setValue('editor.legacyMarkdown', true); }; const onDismissLegacyEditorPrompt = () => { Setting.setValue('editor.pluginCompatibilityBannerDismissedFor', [...PluginService.instance().pluginIds]); }; const incompatiblePluginIds = [ // cSpell:disable 'com.septemberhx.Joplin.Enhancement', 'ylc395.noteLinkSystem', 'joplin.plugin.cmoptions', 'com.asdibiase.joplin-languagetool', // cSpell:enable ]; const WarningBanner: React.FC = props => { const editorMigrationMessage = useEditorTypeMigrationBanner({ markdownEditorEnabled: props.bodyEditor === 'CodeMirror6', editorMigrationVersion: props.editorMigrationVersion, inEditorRenderingEnabled: props.inEditorRenderingEnabled, }); const editorMigrationBanner = ( {editorMigrationMessage.label} ); const lockedInShareBanner = ( {_('This note is read-only because it is locked and contained within a share. To enable editing, it must be moved outside of the share.')} ); const wysiwygBanner = ( {_('This Rich Text editor has a number of limitations and it is recommended to be aware of them before using it.')} ); const incompatiblePluginNames = useMemo(() => { if (props.bodyEditor !== 'CodeMirror6') { return []; } const runningPluginIds = Object.keys(props.plugins); return runningPluginIds.map((id): string|string[] => { if (props.pluginCompatibilityBannerDismissedFor?.includes(id)) { return []; } if (incompatiblePluginIds.includes(id)) { return PluginService.instance().pluginById(id).manifest.name; } else { return []; } }).flat(); }, [props.bodyEditor, props.plugins, props.pluginCompatibilityBannerDismissedFor]); const markdownPluginBanner = ( 0} > {_('The following plugins may not support the current markdown editor:')} ); return <> {lockedInShareBanner} {wysiwygBanner} {markdownPluginBanner} {editorMigrationBanner} ; }; export default connect((state: AppState) => { return { richTextBannerDismissed: state.settings.richTextBannerDismissed, pluginCompatibilityBannerDismissedFor: state.settings['editor.pluginCompatibilityBannerDismissedFor'], plugins: state.pluginService.plugins, editorMigrationVersion: state.settings['editor.migration'], inEditorRenderingEnabled: state.settings['editor.inlineRendering'], }; })(WarningBanner);