2022-08-30 11:05:10 +05:00
|
|
|
import { Editor } from "@notesnook/editor";
|
2022-07-04 16:14:26 +05:00
|
|
|
import {
|
|
|
|
|
MutableRefObject,
|
|
|
|
|
useCallback,
|
|
|
|
|
useEffect,
|
|
|
|
|
useRef,
|
2022-08-30 11:05:10 +05:00
|
|
|
useState
|
2022-07-04 16:14:26 +05:00
|
|
|
} from "react";
|
2022-06-23 19:14:55 +05:00
|
|
|
import { useEditorThemeStore } from "../state/theme";
|
2022-07-20 23:15:04 +05:00
|
|
|
import { EventTypes, isReactNative, post } from "../utils";
|
2022-06-23 19:14:55 +05:00
|
|
|
|
2022-07-04 16:14:26 +05:00
|
|
|
type Attachment = {
|
|
|
|
|
hash: string;
|
|
|
|
|
filename: string;
|
|
|
|
|
type: string;
|
|
|
|
|
size: number;
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-23 19:14:55 +05:00
|
|
|
export type Selection = {
|
|
|
|
|
[name: string]: {
|
|
|
|
|
text?: string;
|
|
|
|
|
length?: number;
|
2022-08-30 11:05:10 +05:00
|
|
|
attributes?: Record<string, unknown>;
|
2022-06-23 19:14:55 +05:00
|
|
|
type?: "mark" | "node";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type Timers = {
|
|
|
|
|
selectionChange: NodeJS.Timeout | null;
|
|
|
|
|
change: NodeJS.Timeout | null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export type EditorController = {
|
|
|
|
|
selectionChange: (editor: Editor) => void;
|
|
|
|
|
titleChange: (title: string) => void;
|
|
|
|
|
contentChange: (editor: Editor) => void;
|
|
|
|
|
scroll: (event: React.UIEvent<HTMLDivElement, UIEvent>) => void;
|
|
|
|
|
title: string;
|
|
|
|
|
setTitle: React.Dispatch<React.SetStateAction<string>>;
|
2022-06-27 18:39:59 +05:00
|
|
|
openFilePicker: (type: "image" | "file" | "camera") => void;
|
2022-06-23 19:14:55 +05:00
|
|
|
downloadAttachment: (attachment: Attachment) => void;
|
2022-07-04 16:14:26 +05:00
|
|
|
content: MutableRefObject<string | null>;
|
2022-07-07 18:40:21 +05:00
|
|
|
onUpdate: () => void;
|
2022-07-08 23:52:45 +05:00
|
|
|
titlePlaceholder: string;
|
|
|
|
|
setTitlePlaceholder: React.Dispatch<React.SetStateAction<string>>;
|
2022-06-23 19:14:55 +05:00
|
|
|
};
|
|
|
|
|
|
2022-07-25 15:44:53 +05:00
|
|
|
export function useEditorController(update: () => void): EditorController {
|
2022-06-23 19:14:55 +05:00
|
|
|
const [title, setTitle] = useState("");
|
2022-07-08 23:52:45 +05:00
|
|
|
const [titlePlaceholder, setTitlePlaceholder] = useState("Note title");
|
2022-07-04 16:14:26 +05:00
|
|
|
const htmlContentRef = useRef<string | null>(null);
|
2022-06-23 19:14:55 +05:00
|
|
|
const timers = useRef<Timers>({
|
|
|
|
|
selectionChange: null,
|
2022-08-30 11:05:10 +05:00
|
|
|
change: null
|
2022-06-23 19:14:55 +05:00
|
|
|
});
|
|
|
|
|
|
2022-08-30 11:05:10 +05:00
|
|
|
const selectionChange = useCallback((_editor: Editor) => {}, []);
|
2022-06-23 19:14:55 +05:00
|
|
|
|
2022-07-25 15:44:53 +05:00
|
|
|
const titleChange = useCallback((title: string) => {
|
2022-06-23 19:14:55 +05:00
|
|
|
post(EventTypes.title, title);
|
2022-07-25 15:44:53 +05:00
|
|
|
}, []);
|
2022-06-23 19:14:55 +05:00
|
|
|
|
2022-07-20 23:15:04 +05:00
|
|
|
const contentChange = useCallback((editor: Editor) => {
|
|
|
|
|
if (!editor) return;
|
|
|
|
|
if (typeof timers.current.change === "number") {
|
|
|
|
|
clearTimeout(timers.current?.change);
|
|
|
|
|
}
|
|
|
|
|
timers.current.change = setTimeout(() => {
|
|
|
|
|
htmlContentRef.current = editor.getHTML();
|
|
|
|
|
post(EventTypes.content, htmlContentRef.current);
|
|
|
|
|
}, 300);
|
|
|
|
|
}, []);
|
2022-06-23 19:14:55 +05:00
|
|
|
|
|
|
|
|
const scroll = useCallback(
|
2022-08-30 11:05:10 +05:00
|
|
|
(_event: React.UIEvent<HTMLDivElement, UIEvent>) => {},
|
2022-06-23 19:14:55 +05:00
|
|
|
[]
|
|
|
|
|
);
|
|
|
|
|
|
2022-07-25 15:44:53 +05:00
|
|
|
const onUpdate = useCallback(() => {
|
2022-07-08 18:33:54 +05:00
|
|
|
update();
|
2022-07-25 15:44:53 +05:00
|
|
|
}, [update]);
|
2022-07-07 18:40:21 +05:00
|
|
|
|
2022-06-23 19:14:55 +05:00
|
|
|
const onMessage = useCallback(
|
2022-08-30 11:05:10 +05:00
|
|
|
(event: Event & { data?: string }) => {
|
|
|
|
|
if (event?.data?.[0] !== "{") return;
|
|
|
|
|
|
|
|
|
|
const message = JSON.parse(event.data);
|
|
|
|
|
const type = message.type;
|
|
|
|
|
const value = message.value;
|
2022-06-23 19:14:55 +05:00
|
|
|
global.sessionId = message.sessionId;
|
|
|
|
|
switch (type) {
|
|
|
|
|
case "native:html":
|
2022-07-04 16:14:26 +05:00
|
|
|
htmlContentRef.current = value;
|
2022-07-08 18:33:54 +05:00
|
|
|
update();
|
2022-06-23 19:14:55 +05:00
|
|
|
break;
|
|
|
|
|
case "native:theme":
|
|
|
|
|
useEditorThemeStore.getState().setColors(message.value);
|
|
|
|
|
break;
|
|
|
|
|
case "native:title":
|
|
|
|
|
setTitle(value);
|
|
|
|
|
break;
|
|
|
|
|
case "native:titleplaceholder":
|
2022-07-08 23:52:45 +05:00
|
|
|
setTitlePlaceholder(value);
|
2022-06-23 19:14:55 +05:00
|
|
|
break;
|
|
|
|
|
case "native:status":
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
post(type); // Notify that message was delivered successfully.
|
|
|
|
|
},
|
2022-07-07 18:40:21 +05:00
|
|
|
[update]
|
2022-06-23 19:14:55 +05:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!isReactNative()) return; // Subscribe only in react native webview.
|
2022-08-30 11:05:10 +05:00
|
|
|
const isSafari = navigator.vendor.match(/apple/i);
|
|
|
|
|
let root: Document | Window = document;
|
2022-06-23 19:14:55 +05:00
|
|
|
if (isSafari) {
|
|
|
|
|
root = window;
|
|
|
|
|
}
|
2022-07-25 15:44:53 +05:00
|
|
|
console.log("recreating messaging");
|
2022-06-23 19:14:55 +05:00
|
|
|
root.addEventListener("message", onMessage);
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
root.removeEventListener("message", onMessage);
|
|
|
|
|
};
|
|
|
|
|
}, [onMessage]);
|
|
|
|
|
|
|
|
|
|
const openFilePicker = useCallback((type) => {
|
|
|
|
|
post(EventTypes.filepicker, type);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const downloadAttachment = useCallback((attachment: Attachment) => {
|
|
|
|
|
post(EventTypes.download, attachment);
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
contentChange,
|
|
|
|
|
selectionChange,
|
|
|
|
|
titleChange,
|
|
|
|
|
scroll,
|
|
|
|
|
title,
|
|
|
|
|
setTitle,
|
2022-07-08 23:52:45 +05:00
|
|
|
titlePlaceholder,
|
|
|
|
|
setTitlePlaceholder,
|
2022-06-23 19:14:55 +05:00
|
|
|
openFilePicker,
|
|
|
|
|
downloadAttachment,
|
2022-07-04 16:14:26 +05:00
|
|
|
content: htmlContentRef,
|
2022-08-30 11:05:10 +05:00
|
|
|
onUpdate: onUpdate
|
2022-06-23 19:14:55 +05:00
|
|
|
};
|
|
|
|
|
}
|