Files
notesnook/packages/editor-mobile/src/utils/index.ts

255 lines
6.4 KiB
TypeScript
Raw Normal View History

/*
This file is part of the Notesnook project (https://notesnook.com/)
2023-01-16 13:44:52 +05:00
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2022-08-30 16:13:11 +05:00
2023-12-21 10:14:53 +05:00
import { Editor, ToolbarGroupDefinition } from "@notesnook/editor";
import { ThemeDefinition } from "@notesnook/theme";
2023-12-21 10:14:53 +05:00
import { Dispatch, MutableRefObject, RefObject, SetStateAction } from "react";
import { EditorController } from "../hooks/useEditorController";
globalThis.sessionId = "notesnook-editor";
2024-01-24 18:58:14 +05:00
globalThis.pendingResolvers = {};
2022-06-23 19:14:55 +05:00
globalThis.pendingResolvers = {};
export function randId(prefix: string) {
return Math.random()
.toString(36)
.replace("0.", prefix || "");
}
2022-06-23 19:14:55 +05:00
export type SafeAreaType = {
top: number;
left: number;
bottom: number;
right: number;
};
export type Settings = {
readonly: boolean;
fullscreen: boolean;
deviceMode: "mobile" | "smallTablet" | "tablet";
premium: boolean;
2022-06-27 18:39:59 +05:00
tools: ToolbarGroupDefinition[];
2022-06-30 09:47:04 +05:00
noToolbar?: boolean;
noHeader?: boolean;
2022-08-06 23:39:07 +05:00
doubleSpacedLines?: boolean;
2023-01-09 13:51:22 +05:00
corsProxy: string;
2023-04-16 01:51:49 +05:00
fontSize: number;
fontFamily: string;
2023-06-05 15:08:40 +05:00
timeFormat: string;
dateFormat: string;
2023-09-15 14:59:52 +05:00
fontScale: number;
2024-03-04 16:10:14 +05:00
markdownShortcuts: boolean;
2022-06-23 19:14:55 +05:00
};
/* eslint-disable no-var */
2022-06-23 19:14:55 +05:00
declare global {
var pendingResolvers: {
[key: string]: (value: any) => void;
};
2023-12-21 10:14:53 +05:00
var statusBars: Record<
number,
| React.MutableRefObject<{
set: React.Dispatch<
React.SetStateAction<{
date: string;
saved: string;
}>
>;
updateWords: () => void;
resetWords: () => void;
}>
2023-12-21 10:14:53 +05:00
| undefined
>;
2023-02-28 13:29:07 +05:00
var __PLATFORM__: "ios" | "android";
2022-06-30 09:47:04 +05:00
var readonly: boolean;
var noToolbar: boolean;
var noHeader: boolean;
2023-11-17 14:20:06 +05:00
function toBlobURL(dataurl: string, id?: string): string | undefined;
2024-01-24 18:58:14 +05:00
var pendingResolvers: { [name: string]: (value: any) => void };
2022-06-23 19:14:55 +05:00
/**
* Id of current session
*/
var sessionId: string;
2023-12-21 10:14:53 +05:00
var tabStore: any;
2022-06-23 19:14:55 +05:00
/**
2023-12-21 10:14:53 +05:00
* Current tiptap editors
2022-06-23 19:14:55 +05:00
*/
2023-12-21 10:14:53 +05:00
var editors: Record<number, Editor | null>;
2022-06-23 19:14:55 +05:00
/**
2023-12-21 10:14:53 +05:00
* Current editor controllers
2022-06-23 19:14:55 +05:00
*/
2023-12-21 10:14:53 +05:00
var editorControllers: Record<number, EditorController | undefined>;
2022-06-23 19:14:55 +05:00
var settingsController: {
update: (settings: Settings) => void;
previous: Settings;
set?: Dispatch<SetStateAction<Settings>>;
};
var premiumController: {
update: (premium: boolean) => void;
previous: boolean;
set?: Dispatch<SetStateAction<boolean>>;
};
var safeAreaController: {
update: (insets: SafeAreaType) => void;
reset: () => void;
previous: SafeAreaType;
set?: Dispatch<
SetStateAction<{
top: number;
bottom: number;
left: number;
right: number;
}>
>;
};
2023-12-21 10:14:53 +05:00
var editorTitles: Record<number, RefObject<HTMLTextAreaElement> | undefined>;
2022-06-23 19:14:55 +05:00
/**
* Global ref to manage tags in editor.
*/
2023-12-21 10:14:53 +05:00
var editorTags: Record<
number,
| MutableRefObject<{
setTags: React.Dispatch<
React.SetStateAction<
{ title: string; alias: string; id: string; type: "tag" }[]
>
>;
}>
| undefined
>;
2022-06-23 19:14:55 +05:00
2022-08-31 13:03:22 +05:00
function logger(type: "info" | "warn" | "error", ...logs: unknown[]): void;
2022-06-23 19:14:55 +05:00
/**
* Function to post message to react native
* @param type
* @param value
*/
function post<T extends keyof typeof EventTypes>(
2023-02-28 13:29:07 +05:00
type: (typeof EventTypes)[T],
2023-12-21 10:14:53 +05:00
value?: unknown,
tabId?: number,
noteId?: string,
sessionId?: string
): void;
2022-06-23 19:14:55 +05:00
interface Window {
/**
* React Native WebView
*/
ReactNativeWebView: {
postMessage: (data: string) => void;
};
}
}
/* eslint-enable no-var */
2022-06-23 19:14:55 +05:00
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",
2022-12-16 22:28:30 +05:00
contentchange: "editor-event:content-change",
reminders: "editor-event:reminders",
2023-07-06 11:10:09 +05:00
previewAttachment: "editor-event:preview-attachment",
copyToClipboard: "editor-events:copy-to-clipboard",
2023-12-21 10:14:53 +05:00
getAttachmentData: "editor-events:get-attachment-data",
tabsChanged: "editor-events:tabs-changed",
showTabs: "editor-events:show-tabs",
2024-01-04 11:38:40 +05:00
tabFocused: "editor-events:tab-focused",
2024-01-24 18:58:14 +05:00
toc: "editor-events:toc",
createInternalLink: "editor-events:create-internal-link"
} as const;
2022-06-23 19:14:55 +05:00
2024-01-24 18:58:14 +05:00
export function randId(prefix: string) {
return Math.random()
.toString(36)
.replace("0.", prefix || "");
}
2022-06-23 19:14:55 +05:00
export function isReactNative(): boolean {
return !!window.ReactNativeWebView;
}
export function logger(
type: "info" | "warn" | "error",
...logs: unknown[]
): void {
const logString = logs
2022-06-23 19:14:55 +05:00
.map((log) => {
return typeof log !== "string" ? JSON.stringify(log) : log;
})
.join(" ");
post(EventTypes.logger, `[${type}]: ` + logString);
}
export function post<T extends keyof typeof EventTypes>(
2023-02-28 13:29:07 +05:00
type: (typeof EventTypes)[T],
value?: unknown,
2023-12-21 10:14:53 +05:00
tabId?: number,
noteId?: string,
sessionId?: string
): void {
2022-06-23 19:14:55 +05:00
if (isReactNative()) {
window.ReactNativeWebView.postMessage(
JSON.stringify({
type,
2022-06-23 19:14:55 +05:00
value: value,
2023-12-21 10:14:53 +05:00
sessionId: sessionId || globalThis.sessionId,
tabId,
noteId
2022-06-23 19:14:55 +05:00
})
);
} else {
// console.log(type, value);
2022-06-23 19:14:55 +05:00
}
}
2022-06-23 19:14:55 +05:00
globalThis.logger = logger;
globalThis.post = post;
export function saveTheme(theme: ThemeDefinition) {
localStorage.setItem("editor-theme", JSON.stringify(theme));
}
export function getTheme() {
const json = localStorage.getItem("editor-theme");
if (json) {
return JSON.parse(json) as ThemeDefinition;
}
return undefined;
}