mobile: fix share extension crash ios (#1651)

Signed-off-by: Ammar Ahmed <40239442+ammarahm-ed@users.noreply.github.com>
This commit is contained in:
Ammar Ahmed
2023-01-13 17:36:21 +05:00
committed by GitHub
parent 44827a1f1a
commit a84611d5ee
4 changed files with 186 additions and 34 deletions

View File

@@ -0,0 +1,19 @@
export const EventTypes = {
selection: "editor-event:selection",
content: "editor-event:content",
title: "editor-event:title",
scroll: "editor-event:scroll",
history: "editor-event:history",
newtag: "editor-event:newtag",
tag: "editor-event:tag",
filepicker: "editor-event:picker",
download: "editor-event:download-attachment",
logger: "native:logger",
back: "editor-event:back",
pro: "editor-event:pro",
monograph: "editor-event:monograph",
properties: "editor-event:properties",
fullscreen: "editor-event:fullscreen",
link: "editor-event:link",
contentchange: "editor-event:content-change"
};

View File

@@ -59,30 +59,10 @@ import { useDragState } from "../../settings/editor/state";
import { EditorMessage, EditorProps, useEditorType } from "./types";
import { EditorEvents, editorState } from "./utils";
import { openLinkInBrowser } from "../../../utils/functions";
import { EventTypes } from "./editor-events";
import { RelationsList } from "../../../components/sheets/relations-list";
import ReminderSheet from "../../../components/sheets/reminder";
export const EventTypes = {
selection: "editor-event:selection",
content: "editor-event:content",
title: "editor-event:title",
scroll: "editor-event:scroll",
history: "editor-event:history",
newtag: "editor-event:newtag",
tag: "editor-event:tag",
filepicker: "editor-event:picker",
download: "editor-event:download-attachment",
logger: "native:logger",
back: "editor-event:back",
pro: "editor-event:pro",
monograph: "editor-event:monograph",
properties: "editor-event:properties",
fullscreen: "editor-event:fullscreen",
link: "editor-event:link",
contentchange: "editor-event:content-change",
reminders: "editor-event:reminders"
};
const publishNote = async (editor: useEditorType) => {
const user = useUserStore.getState().user;
if (!user) {

163
apps/mobile/share/editor.js Normal file
View File

@@ -0,0 +1,163 @@
import React, {
useRef,
useState,
useMemo,
useCallback,
useEffect,
useLayoutEffect
} from "react";
import { WebView } from "react-native-webview";
import { EDITOR_URI } from "../app/screens/editor/source";
import { Linking } from "react-native";
import { EditorEvents, post } from "../app/screens/editor/tiptap/utils";
import Commands from "../app/screens/editor/tiptap/commands";
import { useShareStore } from "./store";
import {
eSubscribeEvent,
eUnSubscribeEvent
} from "../app/services/event-manager";
import { eOnLoadNote } from "../app/utils/events";
import { getDefaultPresets } from "@notesnook/editor/dist/toolbar/tool-definitions";
import { useSettingStore } from "../app/stores/use-setting-store";
import { EventTypes } from "../app/screens/editor/tiptap/editor-events";
const useEditor = () => {
const ref = useRef();
const [sessionId, setSessionId] = useState("share-editor-session");
const colors = useShareStore((state) => state.colors);
const accent = useShareStore((state) => state.accent);
const commands = useMemo(() => new Commands(ref), [ref]);
const currentNote = useRef();
const postMessage = useCallback(
async (type, data) => post(ref, sessionId, type, data),
[]
);
const loadNote = (note) => {
postMessage(EditorEvents.html, note.content.data);
currentNote.current = note;
};
useEffect(() => {
eSubscribeEvent(eOnLoadNote + "shareEditor", loadNote);
return () => {
eUnSubscribeEvent(eOnLoadNote + "shareEditor", loadNote);
};
}, [loadNote]);
const onLoad = () => {
postMessage(EditorEvents.theme, { ...colors, accent });
commands.setInsets({ top: 0, left: 0, right: 0, bottom: 0 });
};
return { ref, onLoad, sessionId, currentNote, commands };
};
const useEditorEvents = (editor,onChange) => {
const doubleSpacedLines = useSettingStore(
(state) => state.settings?.doubleSpacedLines
);
useEffect(() => {
editor.commands.setSettings({
deviceMode: "mobile",
fullscreen: false,
premium: false,
readonly: false,
tools: getDefaultPresets().default,
noHeader: true,
noToolbar: true,
keyboardShown: false,
doubleSpacedLines: doubleSpacedLines
});
}, [editor, doubleSpacedLines]);
const onMessage = (event) => {
const data = event.nativeEvent.data;
const editorMessage = JSON.parse(data);
if (
editorMessage.sessionId !== editor.sessionId &&
editorMessage.type !== EditorEvents.status
) {
return;
}
switch (editorMessage.type) {
case EventTypes.logger:
logger.info("[WEBVIEW LOG]", editorMessage.value);
break;
case EventTypes.content:
logger.info("[WEBVIEW LOG]", "EditorTypes.content");
onChange(editorMessage.value);
break;
}
};
return onMessage;
};
const onShouldStartLoadWithRequest = (request) => {
if (request.url.includes("https")) {
if (Platform.OS === "ios" && !request.isTopFrame) return true;
Linking.openURL(request.url);
return false;
} else {
return true;
}
};
const style = {
height: "100%",
maxHeight: "100%",
width: "100%",
alignSelf: "center",
backgroundColor: "transparent"
};
export const Editor = ({ onChange, onLoad }) => {
const editor = useEditor();
const onMessage = useEditorEvents(editor, onChange);
useLayoutEffect(() => {
onLoad?.();
}, [onLoad]);
return (
<WebView
ref={editor.ref}
onLoad={editor.onLoad}
nestedScrollEnabled
injectedJavaScriptBeforeContentLoaded={`
globalThis.readonly=${false};
globalThis.noToolbar=${true};
globalThis.noHeader=${true};
`}
injectedJavaScript={`globalThis.sessionId="${editor.sessionId}";`}
javaScriptEnabled={true}
focusable={true}
setSupportMultipleWindows={false}
overScrollMode="never"
scrollEnabled={false}
keyboardDisplayRequiresUserAction={false}
cacheMode="LOAD_DEFAULT"
cacheEnabled={true}
domStorageEnabled={true}
bounces={false}
setBuiltInZoomControls={false}
setDisplayZoomControls={false}
allowFileAccess={true}
scalesPageToFit={true}
hideKeyboardAccessoryView={false}
allowsFullscreenVideo={true}
allowFileAccessFromFileURLs={true}
allowUniversalAccessFromFileURLs={true}
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
originWhitelist={["*"]}
source={{
uri: EDITOR_URI
}}
style={style}
autoManageStatusBarEnabled={false}
onMessage={onMessage || undefined}
/>
);
};

View File

@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { getPreviewData } from "@flyerhq/react-native-link-preview";
import { parseHTML } from "@notesnook/core/utils/html-parser";
import React, { useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";
import {
ActivityIndicator,
Alert,
@@ -42,14 +42,13 @@ import ShareExtension from "rn-extensions-share";
import isURL from "validator/lib/isURL";
import { db } from "../app/common/database";
import Storage from "../app/common/database/storage";
import Editor from "../app/screens/editor";
import { eSendEvent } from "../app/services/event-manager";
import { getElevation } from "../app/utils";
import { eOnLoadNote } from "../app/utils/events";
import { sleep } from "../app/utils/time";
import { Search } from "./search";
import { useShareStore } from "./store";
import { useCallback } from "react";
import { sleep } from "../app/utils/time";
import { Editor } from "./editor";
const getLinkPreview = (url) => {
return getPreviewData(url, 5000);
};
@@ -598,15 +597,6 @@ const ShareView = ({ quicknote = false }) => {
>
{!loadingExtension && (
<Editor
ref={editorRef}
theme={{
...colors,
accent
}}
editorId="shareEditor"
noHeader={true}
noToolbar={true}
readonly={false}
onLoad={onLoadEditor}
onChange={(html) => {
noteContent.current = html;