You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2026-04-18 19:42:23 +02:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 812666957c | |||
| dabb7e08b4 |
+3
-2
@@ -456,7 +456,6 @@ packages/app-desktop/gui/WindowCommandsAndDialogs/commands/restoreNote.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/revealResourceFile.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/search.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/setTags.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showEditorPlugin.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showModalMessage.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showNoteContentProperties.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showNoteProperties.js
|
||||
@@ -465,7 +464,6 @@ packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showShareFolderDialog
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showShareNoteDialog.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.test.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditorPlugin.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditors.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleLayoutMoveMode.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleMenuBar.js
|
||||
@@ -1021,7 +1019,9 @@ packages/lib/commands/openMasterPasswordDialog.js
|
||||
packages/lib/commands/permanentlyDeleteNote.js
|
||||
packages/lib/commands/renderMarkup.test.js
|
||||
packages/lib/commands/renderMarkup.js
|
||||
packages/lib/commands/showEditorPlugin.js
|
||||
packages/lib/commands/synchronize.js
|
||||
packages/lib/commands/toggleEditorPlugin.js
|
||||
packages/lib/components/EncryptionConfigScreen/utils.test.js
|
||||
packages/lib/components/EncryptionConfigScreen/utils.js
|
||||
packages/lib/components/shared/NoteList/getEmptyFolderMessage.js
|
||||
@@ -1303,6 +1303,7 @@ packages/lib/services/plugins/utils/getPluginIssueReportUrl.js
|
||||
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
|
||||
packages/lib/services/plugins/utils/getPluginSettingKeyPrefix.js
|
||||
packages/lib/services/plugins/utils/getPluginSettingValue.js
|
||||
packages/lib/services/plugins/utils/getShownPluginEditorView.js
|
||||
packages/lib/services/plugins/utils/isCompatible/getDefaultPlatforms.js
|
||||
packages/lib/services/plugins/utils/isCompatible/index.test.js
|
||||
packages/lib/services/plugins/utils/isCompatible/index.js
|
||||
|
||||
+3
-2
@@ -431,7 +431,6 @@ packages/app-desktop/gui/WindowCommandsAndDialogs/commands/restoreNote.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/revealResourceFile.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/search.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/setTags.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showEditorPlugin.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showModalMessage.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showNoteContentProperties.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showNoteProperties.js
|
||||
@@ -440,7 +439,6 @@ packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showShareFolderDialog
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showShareNoteDialog.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.test.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditorPlugin.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleEditors.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleLayoutMoveMode.js
|
||||
packages/app-desktop/gui/WindowCommandsAndDialogs/commands/toggleMenuBar.js
|
||||
@@ -996,7 +994,9 @@ packages/lib/commands/openMasterPasswordDialog.js
|
||||
packages/lib/commands/permanentlyDeleteNote.js
|
||||
packages/lib/commands/renderMarkup.test.js
|
||||
packages/lib/commands/renderMarkup.js
|
||||
packages/lib/commands/showEditorPlugin.js
|
||||
packages/lib/commands/synchronize.js
|
||||
packages/lib/commands/toggleEditorPlugin.js
|
||||
packages/lib/components/EncryptionConfigScreen/utils.test.js
|
||||
packages/lib/components/EncryptionConfigScreen/utils.js
|
||||
packages/lib/components/shared/NoteList/getEmptyFolderMessage.js
|
||||
@@ -1278,6 +1278,7 @@ packages/lib/services/plugins/utils/getPluginIssueReportUrl.js
|
||||
packages/lib/services/plugins/utils/getPluginNamespacedSettingKey.js
|
||||
packages/lib/services/plugins/utils/getPluginSettingKeyPrefix.js
|
||||
packages/lib/services/plugins/utils/getPluginSettingValue.js
|
||||
packages/lib/services/plugins/utils/getShownPluginEditorView.js
|
||||
packages/lib/services/plugins/utils/isCompatible/getDefaultPlatforms.js
|
||||
packages/lib/services/plugins/utils/isCompatible/index.test.js
|
||||
packages/lib/services/plugins/utils/isCompatible/index.js
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { useMemo } from 'react';
|
||||
import { PluginStates } from '@joplin/lib/services/plugins/reducer';
|
||||
import getActivePluginEditorView from '@joplin/lib/services/plugins/utils/getActivePluginEditorView';
|
||||
import getShownPluginEditorView from '@joplin/lib/services/plugins/utils/getShownPluginEditorView';
|
||||
|
||||
// If a plugin editor should be shown for the current note, this function will return the plugin and
|
||||
// associated view.
|
||||
export default (plugins: PluginStates, shownEditorViewIds: string[]) => {
|
||||
return useMemo(() => {
|
||||
const { editorPlugin, editorView } = getActivePluginEditorView(plugins);
|
||||
if (editorView) {
|
||||
if (!shownEditorViewIds.includes(editorView.id)) return { editorPlugin: null, editorView: null };
|
||||
}
|
||||
return { editorPlugin, editorView };
|
||||
return getShownPluginEditorView(plugins, shownEditorViewIds);
|
||||
}, [plugins, shownEditorViewIds]);
|
||||
};
|
||||
|
||||
@@ -28,7 +28,6 @@ import * as restoreNote from './restoreNote';
|
||||
import * as revealResourceFile from './revealResourceFile';
|
||||
import * as search from './search';
|
||||
import * as setTags from './setTags';
|
||||
import * as showEditorPlugin from './showEditorPlugin';
|
||||
import * as showModalMessage from './showModalMessage';
|
||||
import * as showNoteContentProperties from './showNoteContentProperties';
|
||||
import * as showNoteProperties from './showNoteProperties';
|
||||
@@ -36,7 +35,6 @@ import * as showPrompt from './showPrompt';
|
||||
import * as showShareFolderDialog from './showShareFolderDialog';
|
||||
import * as showShareNoteDialog from './showShareNoteDialog';
|
||||
import * as showSpellCheckerMenu from './showSpellCheckerMenu';
|
||||
import * as toggleEditorPlugin from './toggleEditorPlugin';
|
||||
import * as toggleEditors from './toggleEditors';
|
||||
import * as toggleLayoutMoveMode from './toggleLayoutMoveMode';
|
||||
import * as toggleMenuBar from './toggleMenuBar';
|
||||
@@ -78,7 +76,6 @@ const index: any[] = [
|
||||
revealResourceFile,
|
||||
search,
|
||||
setTags,
|
||||
showEditorPlugin,
|
||||
showModalMessage,
|
||||
showNoteContentProperties,
|
||||
showNoteProperties,
|
||||
@@ -86,7 +83,6 @@ const index: any[] = [
|
||||
showShareFolderDialog,
|
||||
showShareNoteDialog,
|
||||
showSpellCheckerMenu,
|
||||
toggleEditorPlugin,
|
||||
toggleEditors,
|
||||
toggleLayoutMoveMode,
|
||||
toggleMenuBar,
|
||||
|
||||
@@ -25,6 +25,7 @@ import WebBetaButton from './WebBetaButton';
|
||||
|
||||
import Menu, { MenuOptionType } from './Menu';
|
||||
import shim from '@joplin/lib/shim';
|
||||
import CommandService from '@joplin/lib/services/CommandService';
|
||||
export { MenuOptionType };
|
||||
|
||||
// Rather than applying a padding to the whole bar, it is applied to each
|
||||
@@ -67,6 +68,7 @@ interface ScreenHeaderProps {
|
||||
showSideMenuButton?: boolean;
|
||||
showSearchButton?: boolean;
|
||||
showContextMenuButton?: boolean;
|
||||
showPluginEditorButton?: boolean;
|
||||
showBackButton?: boolean;
|
||||
|
||||
saveButtonDisabled?: boolean;
|
||||
@@ -419,6 +421,28 @@ class ScreenHeaderComponent extends PureComponent<ScreenHeaderProps, ScreenHeade
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
const renderTogglePluginEditorButton = (styles: any, onPress: OnPressCallback, disabled: boolean) => {
|
||||
if (!this.props.showPluginEditorButton) return null;
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
onPress={onPress}
|
||||
disabled={disabled}
|
||||
|
||||
themeId={themeId}
|
||||
description={_('Toggle plugin editor')}
|
||||
accessibilityHint={
|
||||
disabled ? null : _('Toggle plugin editor')
|
||||
}
|
||||
contentWrapperStyle={disabled ? styles.iconButtonDisabled : styles.iconButton}
|
||||
|
||||
iconName='ionicon eye'
|
||||
iconStyle={styles.topIcon}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
function deleteButton(styles: any, onPress: OnPressCallback, disabled: boolean) {
|
||||
return (
|
||||
@@ -631,6 +655,8 @@ class ScreenHeaderComponent extends PureComponent<ScreenHeaderProps, ScreenHeade
|
||||
</Menu>
|
||||
);
|
||||
|
||||
const togglePluginEditorButton = renderTogglePluginEditorButton(this.styles(), () => CommandService.instance().execute('toggleEditorPlugin'), false);
|
||||
|
||||
return (
|
||||
<View style={this.styles().container}>
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
@@ -653,6 +679,7 @@ class ScreenHeaderComponent extends PureComponent<ScreenHeaderProps, ScreenHeade
|
||||
{restoreButtonComp}
|
||||
{duplicateButtonComp}
|
||||
{sortButtonComp}
|
||||
{togglePluginEditorButton}
|
||||
{menuComp}
|
||||
</View>
|
||||
<WarningBanner
|
||||
|
||||
@@ -28,7 +28,7 @@ const PluginDialogManager: React.FC<Props> = props => {
|
||||
|
||||
const dialogs: ReactElement[] = [];
|
||||
for (const viewInfo of viewInfos) {
|
||||
if (viewInfo.view.containerType === ContainerType.Panel || !viewInfo.view.opened) {
|
||||
if (viewInfo.view.containerType === ContainerType.Panel || viewInfo.view.containerType === ContainerType.Editor || !viewInfo.view.opened) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import AsyncActionQueue from '@joplin/lib/AsyncActionQueue';
|
||||
import AsyncActionQueue, { IntervalType } from '@joplin/lib/AsyncActionQueue';
|
||||
import uuid from '@joplin/lib/uuid';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import shim from '@joplin/lib/shim';
|
||||
@@ -51,7 +51,7 @@ import { getNoteCallbackUrl } from '@joplin/lib/callbackUrlUtils';
|
||||
import { AppState } from '../../../utils/types';
|
||||
import restoreItems from '@joplin/lib/services/trash/restoreItems';
|
||||
import { getDisplayParentTitle } from '@joplin/lib/services/trash';
|
||||
import { PluginStates, utils as pluginUtils } from '@joplin/lib/services/plugins/reducer';
|
||||
import { PluginHtmlContents, PluginStates, utils as pluginUtils } from '@joplin/lib/services/plugins/reducer';
|
||||
import debounce from '../../../utils/debounce';
|
||||
import { focus } from '@joplin/lib/utils/focusHandler';
|
||||
import CommandService, { RegisteredRuntime } from '@joplin/lib/services/CommandService';
|
||||
@@ -63,6 +63,14 @@ import { DialogContext, DialogControl } from '../../DialogManager';
|
||||
import { CommandRuntimeProps, EditorMode, PickerResponse } from './types';
|
||||
import commands from './commands';
|
||||
import { AttachFileAction, AttachFileOptions } from './commands/attachFile';
|
||||
import { EditorActivationCheckFilterObject } from '@joplin/lib/services/plugins/api/types';
|
||||
import eventManager from '@joplin/lib/eventManager';
|
||||
import PluginService from '@joplin/lib/services/plugins/PluginService';
|
||||
import WebviewController from '@joplin/lib/services/plugins/WebviewController';
|
||||
import PluginUserWebView from '../../plugins/dialogs/PluginUserWebView';
|
||||
import getShownPluginEditorView from '@joplin/lib/services/plugins/utils/getShownPluginEditorView';
|
||||
import getActivePluginEditorView from '@joplin/lib/services/plugins/utils/getActivePluginEditorView';
|
||||
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
const emptyArray: any[] = [];
|
||||
@@ -97,6 +105,9 @@ interface Props extends BaseProps {
|
||||
highlightedWords: string[];
|
||||
noteHash: string;
|
||||
toolbarEnabled: boolean;
|
||||
'plugins.shownEditorViewIds': string[];
|
||||
pluginHtmlContents: PluginHtmlContents;
|
||||
editorNoteReloadTimeRequest: number;
|
||||
}
|
||||
|
||||
interface ComponentProps extends Props {
|
||||
@@ -122,6 +133,7 @@ interface State {
|
||||
imageEditorResourceFilepath: string;
|
||||
noteResources: Record<string, ResourceInfo>;
|
||||
newAndNoTitleChangeNoteId: boolean|null;
|
||||
noteLastLoadTime: number;
|
||||
|
||||
undoRedoButtonState: {
|
||||
canUndo: boolean;
|
||||
@@ -131,6 +143,20 @@ interface State {
|
||||
voiceTypingDialogShown: boolean;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: COPIED FROM DESKTOP
|
||||
const makeNoteUpdateAction = (shownEditorViewIds: string[]) => {
|
||||
return async () => {
|
||||
for (const viewId of shownEditorViewIds) {
|
||||
const controller = PluginService.instance().viewControllerByViewId(viewId) as WebviewController;
|
||||
if (controller) controller.emitUpdate();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> implements BaseNoteScreenComponent {
|
||||
// This isn't in this.state because we don't want changing scroll to trigger
|
||||
// a re-render.
|
||||
@@ -163,6 +189,8 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
||||
public dialogbox: any;
|
||||
private commandRegistration_: RegisteredRuntime|null = null;
|
||||
|
||||
private viewUpdateAsyncQueue_ = new AsyncActionQueue(100, IntervalType.Fixed);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
public static navigationOptions(): any {
|
||||
return { header: null };
|
||||
@@ -189,6 +217,7 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
||||
noteResources: {},
|
||||
imageEditorResourceFilepath: null,
|
||||
newAndNoTitleChangeNoteId: null,
|
||||
noteLastLoadTime: Date.now(),
|
||||
|
||||
undoRedoButtonState: {
|
||||
canUndo: false,
|
||||
@@ -551,6 +580,9 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// TODO: set shownEditorViewIds
|
||||
this.viewUpdateAsyncQueue_.push(makeNoteUpdateAction(['plugin-view-org.joplinapp.plugins.YesYouKan-kanbanBoard']));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
@@ -610,6 +642,28 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
||||
noteHash: noteHash,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.props['plugins.shownEditorViewIds'] !== prevProps['plugins.shownEditorViewIds']) {
|
||||
const { editorPlugin } = getShownPluginEditorView(this.props.plugins, this.props['plugins.shownEditorViewIds']);
|
||||
if (!editorPlugin && this.props.editorNoteReloadTimeRequest > this.state.noteLastLoadTime) {
|
||||
void shared.reloadNote(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// **************** TODO: REUSED FROM DESKTOP APP
|
||||
setTimeout(async () => {
|
||||
let filterObject: EditorActivationCheckFilterObject = {
|
||||
activatedEditors: [],
|
||||
};
|
||||
filterObject = await eventManager.filterEmit('editorActivationCheck', filterObject);
|
||||
|
||||
for (const editor of filterObject.activatedEditors) {
|
||||
const controller = PluginService.instance().pluginById(editor.pluginId).viewController(editor.viewId) as WebviewController;
|
||||
controller.setActive(editor.isActive);
|
||||
}
|
||||
}, 50);
|
||||
// **************** REUSED FROM DESKTOP APP
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
@@ -1420,6 +1474,8 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
||||
// multiple times.
|
||||
this.registerCommands();
|
||||
|
||||
const { editorPlugin, editorView } = getShownPluginEditorView(this.props.plugins, this.props['plugins.shownEditorViewIds']);
|
||||
|
||||
if (this.state.isLoading) {
|
||||
return (
|
||||
<View style={this.styles().screen}>
|
||||
@@ -1448,97 +1504,113 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
||||
/>;
|
||||
}
|
||||
|
||||
const renderPluginEditor = () => {
|
||||
return <PluginUserWebView
|
||||
viewInfo={{ plugin: editorPlugin, view: editorView }}
|
||||
themeId={this.props.themeId}
|
||||
onLoadEnd={() => {}}
|
||||
pluginHtmlContents={this.props.pluginHtmlContents}
|
||||
setDialogControl={() => {}}
|
||||
style={{}}
|
||||
/>;
|
||||
};
|
||||
|
||||
// Currently keyword highlighting is supported only when FTS is available.
|
||||
const keywords = this.props.searchQuery && !!this.props.ftsEnabled ? this.props.highlightedWords : emptyArray;
|
||||
|
||||
let bodyComponent = null;
|
||||
if (this.state.mode === 'view') {
|
||||
// Note: as of 2018-12-29 it's important not to display the viewer if the note body is empty,
|
||||
// to avoid the HACK_webviewLoadingState related bug.
|
||||
bodyComponent =
|
||||
!note || !note.body.trim() ? null : (
|
||||
<NoteBodyViewer
|
||||
onJoplinLinkClick={this.onJoplinLinkClick_}
|
||||
style={this.styles().noteBodyViewer}
|
||||
// Extra bottom padding to make it possible to scroll past the
|
||||
// action button (so that it doesn't overlap the text)
|
||||
paddingBottom={150}
|
||||
noteBody={note.body}
|
||||
noteMarkupLanguage={note.markup_language}
|
||||
noteResources={this.state.noteResources}
|
||||
highlightedKeywords={keywords}
|
||||
themeId={this.props.themeId}
|
||||
fontSize={this.props.viewerFontSize}
|
||||
noteHash={this.props.noteHash}
|
||||
onCheckboxChange={this.onBodyViewerCheckboxChange}
|
||||
onMarkForDownload={this.onMarkForDownload}
|
||||
onRequestEditResource={this.onEditResource}
|
||||
onScroll={this.onBodyViewerScroll}
|
||||
initialScroll={this.lastBodyScroll}
|
||||
pluginStates={this.props.plugins}
|
||||
/>
|
||||
);
|
||||
|
||||
if (editorView) {
|
||||
bodyComponent = renderPluginEditor();
|
||||
} else {
|
||||
// Note: In theory ScrollView can be used to provide smoother scrolling of the TextInput.
|
||||
// However it causes memory or rendering issues on older Android devices, probably because
|
||||
// the whole text input has to be in memory for the scrollview to work. So we keep it as
|
||||
// a plain TextInput for now.
|
||||
// See https://github.com/laurent22/joplin/issues/3041
|
||||
|
||||
// IMPORTANT: The TextInput selection is unreliable and cannot be used in a controlled component
|
||||
// context. In other words, the selection should be considered read-only. For example, if the selection
|
||||
// is saved to the state in onSelectionChange and the current text in onChangeText, then set
|
||||
// back in `selection` and `value` props, it will mostly work. But when typing fast, sooner or
|
||||
// later the real selection will be different from what is stored in the state, thus making
|
||||
// the cursor jump around. Eg, when typing "abcdef", it will do this:
|
||||
// abcd|
|
||||
// abcde|
|
||||
// abcde|f
|
||||
|
||||
if (!this.useEditorBeta()) {
|
||||
bodyComponent = (
|
||||
<TextInput
|
||||
autoCapitalize="sentences"
|
||||
style={this.styles().bodyTextInput}
|
||||
ref="noteBodyTextField"
|
||||
multiline={true}
|
||||
value={note.body}
|
||||
onChangeText={this.onPlainEditorTextChange}
|
||||
onSelectionChange={this.onPlainEditorSelectionChange}
|
||||
blurOnSubmit={false}
|
||||
selectionColor={theme.textSelectionColor}
|
||||
keyboardAppearance={theme.keyboardAppearance}
|
||||
placeholder={_('Add body')}
|
||||
placeholderTextColor={theme.colorFaded}
|
||||
// need some extra padding for iOS so that the keyboard won't cover last line of the note
|
||||
// see https://github.com/laurent22/joplin/issues/3607
|
||||
// Property is gone as of RN 0.72?
|
||||
// paddingBottom={ (Platform.OS === 'ios' ? 40 : 0) as any}
|
||||
/>
|
||||
);
|
||||
if (this.state.mode === 'view') {
|
||||
// Note: as of 2018-12-29 it's important not to display the viewer if the note body is empty,
|
||||
// to avoid the HACK_webviewLoadingState related bug.
|
||||
bodyComponent =
|
||||
!note || !note.body.trim() ? null : (
|
||||
<NoteBodyViewer
|
||||
onJoplinLinkClick={this.onJoplinLinkClick_}
|
||||
style={this.styles().noteBodyViewer}
|
||||
// Extra bottom padding to make it possible to scroll past the
|
||||
// action button (so that it doesn't overlap the text)
|
||||
paddingBottom={150}
|
||||
noteBody={note.body}
|
||||
noteMarkupLanguage={note.markup_language}
|
||||
noteResources={this.state.noteResources}
|
||||
highlightedKeywords={keywords}
|
||||
themeId={this.props.themeId}
|
||||
fontSize={this.props.viewerFontSize}
|
||||
noteHash={this.props.noteHash}
|
||||
onCheckboxChange={this.onBodyViewerCheckboxChange}
|
||||
onMarkForDownload={this.onMarkForDownload}
|
||||
onRequestEditResource={this.onEditResource}
|
||||
onScroll={this.onBodyViewerScroll}
|
||||
initialScroll={this.lastBodyScroll}
|
||||
pluginStates={this.props.plugins}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
const editorStyle = this.styles().bodyTextInput;
|
||||
// Note: In theory ScrollView can be used to provide smoother scrolling of the TextInput.
|
||||
// However it causes memory or rendering issues on older Android devices, probably because
|
||||
// the whole text input has to be in memory for the scrollview to work. So we keep it as
|
||||
// a plain TextInput for now.
|
||||
// See https://github.com/laurent22/joplin/issues/3041
|
||||
|
||||
bodyComponent = <NoteEditor
|
||||
ref={this.editorRef}
|
||||
toolbarEnabled={this.props.toolbarEnabled}
|
||||
themeId={this.props.themeId}
|
||||
initialText={note.body}
|
||||
initialSelection={this.selection}
|
||||
onChange={this.onMarkdownEditorTextChange}
|
||||
onSelectionChange={this.onMarkdownEditorSelectionChange}
|
||||
onUndoRedoDepthChange={this.onUndoRedoDepthChange}
|
||||
onAttach={this.onAttach}
|
||||
readOnly={this.state.readOnly}
|
||||
plugins={this.props.plugins}
|
||||
style={{
|
||||
...editorStyle,
|
||||
// IMPORTANT: The TextInput selection is unreliable and cannot be used in a controlled component
|
||||
// context. In other words, the selection should be considered read-only. For example, if the selection
|
||||
// is saved to the state in onSelectionChange and the current text in onChangeText, then set
|
||||
// back in `selection` and `value` props, it will mostly work. But when typing fast, sooner or
|
||||
// later the real selection will be different from what is stored in the state, thus making
|
||||
// the cursor jump around. Eg, when typing "abcdef", it will do this:
|
||||
// abcd|
|
||||
// abcde|
|
||||
// abcde|f
|
||||
|
||||
// Allow the editor to set its own padding
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
}}
|
||||
/>;
|
||||
if (!this.useEditorBeta()) {
|
||||
bodyComponent = (
|
||||
<TextInput
|
||||
autoCapitalize="sentences"
|
||||
style={this.styles().bodyTextInput}
|
||||
ref="noteBodyTextField"
|
||||
multiline={true}
|
||||
value={note.body}
|
||||
onChangeText={this.onPlainEditorTextChange}
|
||||
onSelectionChange={this.onPlainEditorSelectionChange}
|
||||
blurOnSubmit={false}
|
||||
selectionColor={theme.textSelectionColor}
|
||||
keyboardAppearance={theme.keyboardAppearance}
|
||||
placeholder={_('Add body')}
|
||||
placeholderTextColor={theme.colorFaded}
|
||||
// need some extra padding for iOS so that the keyboard won't cover last line of the note
|
||||
// see https://github.com/laurent22/joplin/issues/3607
|
||||
// Property is gone as of RN 0.72?
|
||||
// paddingBottom={ (Platform.OS === 'ios' ? 40 : 0) as any}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
const editorStyle = this.styles().bodyTextInput;
|
||||
|
||||
bodyComponent = <NoteEditor
|
||||
ref={this.editorRef}
|
||||
toolbarEnabled={this.props.toolbarEnabled}
|
||||
themeId={this.props.themeId}
|
||||
initialText={note.body}
|
||||
initialSelection={this.selection}
|
||||
onChange={this.onMarkdownEditorTextChange}
|
||||
onSelectionChange={this.onMarkdownEditorSelectionChange}
|
||||
onUndoRedoDepthChange={this.onUndoRedoDepthChange}
|
||||
onAttach={this.onAttach}
|
||||
readOnly={this.state.readOnly}
|
||||
plugins={this.props.plugins}
|
||||
style={{
|
||||
...editorStyle,
|
||||
|
||||
// Allow the editor to set its own padding
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
}}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1595,6 +1667,8 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
||||
return <VoiceTypingDialog locale={currentLocale()} onText={this.voiceTypingDialog_onText} onDismiss={this.voiceTypingDialog_onDismiss}/>;
|
||||
};
|
||||
|
||||
const { editorPlugin: activeEditorPlugin } = getActivePluginEditorView(this.props.plugins);
|
||||
|
||||
return (
|
||||
<View style={this.rootStyle(this.props.themeId).root}>
|
||||
<ScreenHeader
|
||||
@@ -1607,6 +1681,7 @@ class NoteScreenComponent extends BaseScreenComponent<ComponentProps, State> imp
|
||||
showSearchButton={false}
|
||||
showUndoButton={(this.state.undoRedoButtonState.canUndo || this.state.undoRedoButtonState.canRedo) && this.state.mode === 'edit'}
|
||||
showRedoButton={this.state.undoRedoButtonState.canRedo && this.state.mode === 'edit'}
|
||||
showPluginEditorButton={!!activeEditorPlugin}
|
||||
undoButtonDisabled={!this.state.undoRedoButtonState.canUndo && this.state.undoRedoButtonState.canRedo}
|
||||
onUndoButtonPress={this.screenHeader_undoButtonPress}
|
||||
onRedoButtonPress={this.screenHeader_redoButtonPress}
|
||||
@@ -1654,6 +1729,9 @@ const NoteScreen = connect((state: AppState) => {
|
||||
provisionalNoteIds: state.provisionalNoteIds,
|
||||
highlightedWords: state.highlightedWords,
|
||||
plugins: state.pluginService.plugins,
|
||||
'plugins.shownEditorViewIds': state.settings['plugins.shownEditorViewIds'] || [],
|
||||
pluginHtmlContents: state.pluginService.pluginHtmlContents,
|
||||
editorNoteReloadTimeRequest: state.editorNoteReloadTimeRequest,
|
||||
|
||||
// What we call "beta editor" in this component is actually the (now
|
||||
// default) CodeMirror editor. That should be refactored to make it less
|
||||
|
||||
@@ -288,7 +288,14 @@ class NotesScreenComponent extends BaseScreenComponent<ComponentProps, State> {
|
||||
|
||||
inert={accessibilityHidden}
|
||||
>
|
||||
<ScreenHeader title={iconString + title} showBackButton={false} sortButton_press={this.sortButton_press} folderPickerOptions={this.folderPickerOptions()} showSearchButton={true} showSideMenuButton={true} />
|
||||
<ScreenHeader
|
||||
title={iconString + title}
|
||||
showBackButton={false}
|
||||
sortButton_press={this.sortButton_press}
|
||||
folderPickerOptions={this.folderPickerOptions()}
|
||||
showSearchButton={true}
|
||||
showSideMenuButton={true}
|
||||
/>
|
||||
<NoteList />
|
||||
{actionButtonComp}
|
||||
</AccessibleView>
|
||||
|
||||
@@ -1 +1 @@
|
||||
module.exports = {"hash":"cfa07333af79f4db4bc9ca008fb257f8","files":["highlight.js/atom-one-dark-reasonable.css","highlight.js/atom-one-light.css","katex/fonts/KaTeX_AMS-Regular.woff2","katex/fonts/KaTeX_Caligraphic-Bold.woff2","katex/fonts/KaTeX_Caligraphic-Regular.woff2","katex/fonts/KaTeX_Fraktur-Bold.woff2","katex/fonts/KaTeX_Fraktur-Regular.woff2","katex/fonts/KaTeX_Main-Bold.woff2","katex/fonts/KaTeX_Main-BoldItalic.woff2","katex/fonts/KaTeX_Main-Italic.woff2","katex/fonts/KaTeX_Main-Regular.woff2","katex/fonts/KaTeX_Math-BoldItalic.woff2","katex/fonts/KaTeX_Math-Italic.woff2","katex/fonts/KaTeX_SansSerif-Bold.woff2","katex/fonts/KaTeX_SansSerif-Italic.woff2","katex/fonts/KaTeX_SansSerif-Regular.woff2","katex/fonts/KaTeX_Script-Regular.woff2","katex/fonts/KaTeX_Size1-Regular.woff2","katex/fonts/KaTeX_Size2-Regular.woff2","katex/fonts/KaTeX_Size3-Regular.woff2","katex/fonts/KaTeX_Size4-Regular.woff2","katex/fonts/KaTeX_Typewriter-Regular.woff2","katex/katex.css","mermaid/mermaid.min.js","mermaid/mermaid_render.js"]}
|
||||
module.exports = {"hash":"cfa07333af79f4db4bc9ca008fb257f8","files":[".DS_Store","highlight.js/atom-one-dark-reasonable.css","highlight.js/atom-one-light.css","katex/fonts/KaTeX_AMS-Regular.woff2","katex/fonts/KaTeX_Caligraphic-Bold.woff2","katex/fonts/KaTeX_Caligraphic-Regular.woff2","katex/fonts/KaTeX_Fraktur-Bold.woff2","katex/fonts/KaTeX_Fraktur-Regular.woff2","katex/fonts/KaTeX_Main-Bold.woff2","katex/fonts/KaTeX_Main-BoldItalic.woff2","katex/fonts/KaTeX_Main-Italic.woff2","katex/fonts/KaTeX_Main-Regular.woff2","katex/fonts/KaTeX_Math-BoldItalic.woff2","katex/fonts/KaTeX_Math-Italic.woff2","katex/fonts/KaTeX_SansSerif-Bold.woff2","katex/fonts/KaTeX_SansSerif-Italic.woff2","katex/fonts/KaTeX_SansSerif-Regular.woff2","katex/fonts/KaTeX_Script-Regular.woff2","katex/fonts/KaTeX_Size1-Regular.woff2","katex/fonts/KaTeX_Size2-Regular.woff2","katex/fonts/KaTeX_Size3-Regular.woff2","katex/fonts/KaTeX_Size4-Regular.woff2","katex/fonts/KaTeX_Typewriter-Regular.woff2","katex/katex.css","mermaid/mermaid.min.js","mermaid/mermaid_render.js"]}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
hash: '55cc4fcf19c129e3824873d98ad417c9', files: {
|
||||
'fontawesome/css/all.min.css': { data: require('./fontawesome/css/all.min.css.base64.js'), mime: 'text/css', encoding: 'base64' },
|
||||
'fontawesome/webfonts/fa-brands-400.ttf': { data: require('./fontawesome/webfonts/fa-brands-400.ttf.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
'fontawesome/webfonts/fa-brands-400.woff2': { data: require('./fontawesome/webfonts/fa-brands-400.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
'fontawesome/webfonts/fa-regular-400.ttf': { data: require('./fontawesome/webfonts/fa-regular-400.ttf.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
'fontawesome/webfonts/fa-regular-400.woff2': { data: require('./fontawesome/webfonts/fa-regular-400.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
'fontawesome/webfonts/fa-solid-900.ttf': { data: require('./fontawesome/webfonts/fa-solid-900.ttf.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
'fontawesome/webfonts/fa-solid-900.woff2': { data: require('./fontawesome/webfonts/fa-solid-900.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
'fontawesome/webfonts/fa-v4compatibility.ttf': { data: require('./fontawesome/webfonts/fa-v4compatibility.ttf.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
'fontawesome/webfonts/fa-v4compatibility.woff2': { data: require('./fontawesome/webfonts/fa-v4compatibility.woff2.base64.js'), mime: 'application/octet-stream', encoding: 'base64' },
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = { 'hash': '55cc4fcf19c129e3824873d98ad417c9', 'files': ['fontawesome/css/all.min.css', 'fontawesome/webfonts/fa-brands-400.ttf', 'fontawesome/webfonts/fa-brands-400.woff2', 'fontawesome/webfonts/fa-regular-400.ttf', 'fontawesome/webfonts/fa-regular-400.woff2', 'fontawesome/webfonts/fa-solid-900.ttf', 'fontawesome/webfonts/fa-solid-900.woff2', 'fontawesome/webfonts/fa-v4compatibility.ttf', 'fontawesome/webfonts/fa-v4compatibility.woff2'] };
|
||||
@@ -5,7 +5,7 @@ const path = require('path');
|
||||
const md5 = require('md5');
|
||||
|
||||
const rootDir = `${__dirname}/..`;
|
||||
const outputDir = `${rootDir}/pluginAssets`;
|
||||
const defaultOutputDir = `${rootDir}/pluginAssets`;
|
||||
|
||||
const walk = function(dir) {
|
||||
let results = [];
|
||||
@@ -37,7 +37,7 @@ const readAsBase64 = async (path, mime) => {
|
||||
return buffer.toString('base64');
|
||||
};
|
||||
|
||||
async function encodeFile(sourcePath, destPath) {
|
||||
async function encodeFile(sourcePath, destPath, outputDir) {
|
||||
const ext = utils.fileExtension(sourcePath).toLowerCase();
|
||||
let mime = 'application/octet-stream';
|
||||
if (ext === 'js') mime = 'application/javascript';
|
||||
@@ -60,19 +60,35 @@ async function encodeFile(sourcePath, destPath) {
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const copyFontAwesomeAssets = async () => {
|
||||
const sourceDir = `${rootDir}/node_modules/@fortawesome/fontawesome-free`;
|
||||
const targetDir = `${rootDir}/fontawesome-temp`;
|
||||
await fs.remove(targetDir);
|
||||
|
||||
await fs.mkdirp(`${targetDir}/fontawesome/css`);
|
||||
await fs.mkdirp(`${targetDir}/fontawesome/webfonts`);
|
||||
|
||||
await fs.copyFile(`${sourceDir}/css/all.min.css`, `${targetDir}/fontawesome/css/all.min.css`);
|
||||
await fs.copy(`${sourceDir}/webfonts`, `${targetDir}/fontawesome/webfonts`);
|
||||
|
||||
return targetDir;
|
||||
};
|
||||
|
||||
const encodeDirectory = async (sourceAssetDir) => {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
try {
|
||||
const outputDir = sourceAssetDir.destination ? sourceAssetDir.destination : defaultOutputDir;
|
||||
|
||||
await fs.remove(outputDir);
|
||||
await utils.mkdirp(outputDir);
|
||||
|
||||
const encodedFiles = [];
|
||||
const sourceAssetDir = `${rootDir}/../renderer/assets`;
|
||||
const files = walk(sourceAssetDir);
|
||||
const files = walk(sourceAssetDir.source);
|
||||
|
||||
for (const file of files) {
|
||||
const destFile = file.substr(sourceAssetDir.length + 1);
|
||||
encodedFiles.push(await encodeFile(file, destFile));
|
||||
if (file.endsWith('.DS_Store')) continue;
|
||||
const destFile = file.substr(sourceAssetDir.source.length + 1);
|
||||
encodedFiles.push(await encodeFile(file, destFile, outputDir));
|
||||
}
|
||||
|
||||
const hashes = [];
|
||||
@@ -87,7 +103,7 @@ async function main() {
|
||||
await fs.writeFile(`${outputDir}/index.js`, `module.exports = {\nhash:"${hash}", files: {\n${indexJs.join('\n')}\n}\n};`);
|
||||
await fs.writeFile(`${outputDir}/index.web.js`, `module.exports = ${JSON.stringify({
|
||||
hash,
|
||||
files: files.map(file => toForwardSlashes(path.relative(sourceAssetDir, file))),
|
||||
files: files.map(file => toForwardSlashes(path.relative(sourceAssetDir.source, file))),
|
||||
})}`);
|
||||
|
||||
return;
|
||||
@@ -115,6 +131,28 @@ async function main() {
|
||||
}
|
||||
|
||||
throw new Error('Could not encode file after multiple attempts. See above for errors.');
|
||||
};
|
||||
|
||||
async function main() {
|
||||
const fontAwesomeAssetDir = await copyFontAwesomeAssets();
|
||||
|
||||
const sourceAssetDirs = [
|
||||
{
|
||||
source: `${rootDir}/../renderer/assets`,
|
||||
},
|
||||
{
|
||||
source: fontAwesomeAssetDir,
|
||||
destination: `${rootDir}/plugins/pluginUserWebViewAssets/fontawesome`,
|
||||
},
|
||||
];
|
||||
|
||||
try {
|
||||
for (const sourceAssetDir of sourceAssetDirs) {
|
||||
await encodeDirectory(sourceAssetDir);
|
||||
}
|
||||
} finally {
|
||||
await fs.remove(fontAwesomeAssetDir);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = main;
|
||||
|
||||
@@ -5,7 +5,9 @@ import * as historyForward from './historyForward';
|
||||
import * as openMasterPasswordDialog from './openMasterPasswordDialog';
|
||||
import * as permanentlyDeleteNote from './permanentlyDeleteNote';
|
||||
import * as renderMarkup from './renderMarkup';
|
||||
import * as showEditorPlugin from './showEditorPlugin';
|
||||
import * as synchronize from './synchronize';
|
||||
import * as toggleEditorPlugin from './toggleEditorPlugin';
|
||||
|
||||
const index: any[] = [
|
||||
deleteNote,
|
||||
@@ -14,7 +16,9 @@ const index: any[] = [
|
||||
openMasterPasswordDialog,
|
||||
permanentlyDeleteNote,
|
||||
renderMarkup,
|
||||
showEditorPlugin,
|
||||
synchronize,
|
||||
toggleEditorPlugin,
|
||||
];
|
||||
|
||||
export default index;
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { CommandContext, CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import getActivePluginEditorView from '@joplin/lib/services/plugins/utils/getActivePluginEditorView';
|
||||
import { CommandContext, CommandDeclaration, CommandRuntime } from '../services/CommandService';
|
||||
import Setting from '../models/Setting';
|
||||
import getActivePluginEditorView from '../services/plugins/utils/getActivePluginEditorView';
|
||||
import Logger from '@joplin/utils/Logger';
|
||||
|
||||
const logger = Logger.create('showEditorPlugin');
|
||||
+16
-4
@@ -1,7 +1,7 @@
|
||||
import { CommandContext, CommandDeclaration, CommandRuntime } from '@joplin/lib/services/CommandService';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import getActivePluginEditorView from '@joplin/lib/services/plugins/utils/getActivePluginEditorView';
|
||||
import { CommandContext, CommandDeclaration, CommandRuntime } from '../services/CommandService';
|
||||
import { _ } from '../locale';
|
||||
import Setting from '../models/Setting';
|
||||
import getActivePluginEditorView from '../services/plugins/utils/getActivePluginEditorView';
|
||||
import Logger from '@joplin/utils/Logger';
|
||||
|
||||
const logger = Logger.create('toggleEditorPlugin');
|
||||
@@ -24,14 +24,26 @@ export const runtime = (): CommandRuntime => {
|
||||
}
|
||||
|
||||
const idx = shownEditorViewIds.indexOf(editorView.id);
|
||||
let hasBeenHidden = false;
|
||||
|
||||
if (idx < 0) {
|
||||
shownEditorViewIds.push(editorView.id);
|
||||
} else {
|
||||
shownEditorViewIds.splice(idx, 1);
|
||||
hasBeenHidden = true;
|
||||
}
|
||||
|
||||
logger.info('New shown editor views: ', shownEditorViewIds);
|
||||
|
||||
Setting.setValue('plugins.shownEditorViewIds', shownEditorViewIds);
|
||||
|
||||
if (hasBeenHidden) {
|
||||
// When the plugin editor goes from visible to hidden, we need to reload the note
|
||||
// because it may have been changed via the data API.
|
||||
context.dispatch({
|
||||
type: 'EDITOR_NOTE_NEEDS_RELOAD',
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -67,6 +67,8 @@ interface Shared {
|
||||
installResourceHandling?: (refreshResourceHandler: any)=> void;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
uninstallResourceHandling?: (refreshResourceHandler: any)=> void;
|
||||
|
||||
reloadNote?: (comp: BaseNoteScreenComponent)=> Promise<NoteEntity>;
|
||||
}
|
||||
|
||||
const shared: Shared = {};
|
||||
@@ -268,7 +270,7 @@ shared.isModified = function(comp: BaseNoteScreenComponent) {
|
||||
return !!Object.getOwnPropertyNames(diff).length;
|
||||
};
|
||||
|
||||
shared.initState = async function(comp: BaseNoteScreenComponent) {
|
||||
shared.reloadNote = async (comp: BaseNoteScreenComponent) => {
|
||||
const isProvisionalNote = comp.props.provisionalNoteIds.includes(comp.props.noteId);
|
||||
|
||||
const note = await Note.load(comp.props.noteId);
|
||||
@@ -292,6 +294,7 @@ shared.initState = async function(comp: BaseNoteScreenComponent) {
|
||||
fromShare: !!comp.props.sharedData,
|
||||
noteResources: await shared.attachedResources(note ? note.body : ''),
|
||||
readOnly: itemIsReadOnlySync(ModelType.Note, ItemChange.SOURCE_UNSPECIFIED, note as ItemSlice, Setting.value('sync.userId'), BaseItem.syncShareCache),
|
||||
noteLastLoadTime: Date.now(),
|
||||
});
|
||||
} else {
|
||||
// Handle the case where a non-existent note is loaded. This can happen briefly after deleting a note.
|
||||
@@ -304,9 +307,16 @@ shared.initState = async function(comp: BaseNoteScreenComponent) {
|
||||
fromShare,
|
||||
noteResources: [],
|
||||
readOnly: true,
|
||||
noteLastLoadTime: Date.now(),
|
||||
});
|
||||
}
|
||||
|
||||
return note;
|
||||
};
|
||||
|
||||
shared.initState = async function(comp: BaseNoteScreenComponent) {
|
||||
const note = await shared.reloadNote(comp);
|
||||
|
||||
if (comp.props.sharedData) {
|
||||
if (comp.props.sharedData.title) {
|
||||
this.noteComponent_change(comp, 'title', comp.props.sharedData.title);
|
||||
|
||||
@@ -170,6 +170,7 @@ export interface State extends WindowState {
|
||||
mustUpgradeAppMessage: string;
|
||||
mustAuthenticate: boolean;
|
||||
toast: Toast | null;
|
||||
editorNoteReloadTimeRequest: number;
|
||||
|
||||
allowSelectionInOtherFolders: boolean;
|
||||
|
||||
@@ -241,6 +242,7 @@ export const defaultState: State = {
|
||||
mustUpgradeAppMessage: '',
|
||||
mustAuthenticate: false,
|
||||
allowSelectionInOtherFolders: false,
|
||||
editorNoteReloadTimeRequest: 0,
|
||||
|
||||
pluginService: pluginServiceDefaultState,
|
||||
shareService: shareServiceDefaultState,
|
||||
@@ -1512,6 +1514,12 @@ const reducer = produce((draft: Draft<State> = defaultState, action: any) => {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'EDITOR_NOTE_NEEDS_RELOAD':
|
||||
{
|
||||
draft.editorNoteReloadTimeRequest = Date.now();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'TOAST_SHOW':
|
||||
draft.toast = {
|
||||
duration: 6000,
|
||||
|
||||
@@ -157,10 +157,13 @@ export default class WebviewController extends ViewController {
|
||||
public emitUpdate() {
|
||||
if (!this.updateListener_) return;
|
||||
|
||||
if (this.containerType_ === ContainerType.Editor && (!this.isActive() || !this.isVisible())) {
|
||||
logger.info('emitMessage: Not emitting update because editor is disabled or hidden:', this.pluginId, this.handle, this.isActive(), this.isVisible());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
|
||||
// if (this.containerType_ === ContainerType.Editor && (!this.isActive() || !this.isVisible())) {
|
||||
// logger.info('emitMessage: Not emitting update because editor is disabled or hidden:', this.pluginId, this.handle, this.isActive(), this.isVisible());
|
||||
// return;
|
||||
// }
|
||||
|
||||
this.updateListener_();
|
||||
}
|
||||
@@ -279,7 +282,7 @@ export default class WebviewController extends ViewController {
|
||||
return this.storeView.opened;
|
||||
}
|
||||
|
||||
public async isVisible(): Promise<boolean> {
|
||||
public isVisible(): boolean {
|
||||
if (!this.storeView.opened) return false;
|
||||
const shownEditorViewIds: string[] = this.store.getState().settings['plugins.shownEditorViewIds'];
|
||||
return shownEditorViewIds.includes(this.handle);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { PluginStates } from '../reducer';
|
||||
import getActivePluginEditorView from './getActivePluginEditorView';
|
||||
|
||||
export default (plugins: PluginStates, shownEditorViewIds: string[]) => {
|
||||
const { editorPlugin, editorView } = getActivePluginEditorView(plugins);
|
||||
if (editorView) {
|
||||
if (!shownEditorViewIds.includes(editorView.id)) return { editorPlugin: null, editorView: null };
|
||||
}
|
||||
return { editorPlugin, editorView };
|
||||
};
|
||||
@@ -7468,6 +7468,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@fortawesome/fontawesome-free@npm:^6.7.2":
|
||||
version: 6.7.2
|
||||
resolution: "@fortawesome/fontawesome-free@npm:6.7.2"
|
||||
checksum: 2ceb384ada8e4a1e8a8e24384a35e3afa01589ddec67c8c52e3ad5d7db1662d0fc92560bd9a23baa4e0676e721e423aef99fb79fe6899bf13900fd1e611b6760
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@fortawesome/fontawesome-svg-core@npm:6.1.2":
|
||||
version: 6.1.2
|
||||
resolution: "@fortawesome/fontawesome-svg-core@npm:6.1.2"
|
||||
@@ -8355,6 +8362,7 @@ __metadata:
|
||||
"@babel/preset-env": 7.24.7
|
||||
"@babel/runtime": 7.24.7
|
||||
"@bam.tech/react-native-image-resizer": 3.0.10
|
||||
"@fortawesome/fontawesome-free": ^6.7.2
|
||||
"@joplin/editor": ~3.3
|
||||
"@joplin/lib": ~3.3
|
||||
"@joplin/react-native-alarm-notification": ~3.3
|
||||
|
||||
Reference in New Issue
Block a user