mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Merge branch 'master' of github.com:excalidraw/excalidraw into cleanipp
* 'master' of github.com:excalidraw/excalidraw: (37 commits) feat: Add toast (#2772) docs: Update readme with documentation (#2788) fix: allow text-selecting in dialogs & reset cursor (#2783) chore: Update translations from Crowdin (#2742) fix: broken Individuals link (#2782) refactor: Converting span to kbd tag (#2774) fix: don't render due to zoom after unmount (#2779) fix: Track the chart type correctly (#2773) chore(deps-dev): bump terser-webpack-plugin in /src/packages/excalidraw (#2750) chore(deps-dev): bump webpack in /src/packages/utils (#2768) fix: delay version logging & prevent duplicates (#2770) chore(deps-dev): bump webpack in /src/packages/excalidraw (#2769) chore(deps-dev): bump ts-loader in /src/packages/excalidraw (#2749) chore(deps-dev): bump ts-loader in /src/packages/utils (#2753) chore(deps): bump nanoid from 2.1.11 to 3.1.20 (#2581) feat: Track current version (#2731) chore(actions): Use cancel workflow action (#2763) chore(deps): bump @testing-library/react from 11.2.2 to 11.2.3 (#2755) chore(deps-dev): bump firebase-tools from 9.1.0 to 9.1.2 (#2761) chore(deps-dev): bump eslint-plugin-prettier from 3.3.0 to 3.3.1 (#2754) ...
This commit is contained in:
commit
1eb8920bc3
115 changed files with 2445 additions and 4938 deletions
|
@ -1,34 +1,53 @@
|
|||
import React, { useState, useLayoutEffect, useEffect, useRef } from "react";
|
||||
|
||||
import Excalidraw from "../packages/excalidraw/index";
|
||||
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { trackEvent } from "../analytics";
|
||||
import { getDefaultAppState } from "../appState";
|
||||
import { ExcalidrawImperativeAPI } from "../components/App";
|
||||
import { ErrorDialog } from "../components/ErrorDialog";
|
||||
import { TopErrorBoundary } from "../components/TopErrorBoundary";
|
||||
import { APP_NAME, EVENT, TITLE_TIMEOUT } from "../constants";
|
||||
import { ImportedDataState } from "../data/types";
|
||||
import {
|
||||
ExcalidrawElement,
|
||||
NonDeletedExcalidrawElement,
|
||||
} from "../element/types";
|
||||
import { Language, t } from "../i18n";
|
||||
import Excalidraw, {
|
||||
defaultLang,
|
||||
languages,
|
||||
} from "../packages/excalidraw/index";
|
||||
import { AppState, ExcalidrawAPIRefValue } from "../types";
|
||||
import {
|
||||
debounce,
|
||||
getVersion,
|
||||
ResolvablePromise,
|
||||
resolvablePromise,
|
||||
} from "../utils";
|
||||
import { SAVE_TO_LOCAL_STORAGE_TIMEOUT } from "./app_constants";
|
||||
import CollabWrapper, { CollabAPI } from "./collab/CollabWrapper";
|
||||
import { LanguageList } from "./components/LanguageList";
|
||||
import { exportToBackend, getCollaborationLinkData, loadScene } from "./data";
|
||||
import { loadFromFirebase } from "./data/firebase";
|
||||
import {
|
||||
getTotalStorageSize,
|
||||
importFromLocalStorage,
|
||||
saveToLocalStorage,
|
||||
STORAGE_KEYS,
|
||||
} from "./data/localStorage";
|
||||
|
||||
import { ImportedDataState } from "../data/types";
|
||||
import CollabWrapper, { CollabAPI } from "./collab/CollabWrapper";
|
||||
import { TopErrorBoundary } from "../components/TopErrorBoundary";
|
||||
import { t } from "../i18n";
|
||||
import { exportToBackend, loadScene } from "./data";
|
||||
import { getCollaborationLinkData } from "./data";
|
||||
import { EVENT } from "../constants";
|
||||
import { loadFromFirebase } from "./data/firebase";
|
||||
import { ExcalidrawImperativeAPI } from "../components/App";
|
||||
import { debounce, ResolvablePromise, resolvablePromise } from "../utils";
|
||||
import { AppState, ExcalidrawAPIRefValue } from "../types";
|
||||
import {
|
||||
ExcalidrawElement,
|
||||
NonDeletedExcalidrawElement,
|
||||
} from "../element/types";
|
||||
import { SAVE_TO_LOCAL_STORAGE_TIMEOUT } from "./app_constants";
|
||||
import { EVENT_LOAD, EVENT_SHARE, trackEvent } from "../analytics";
|
||||
import { ErrorDialog } from "../components/ErrorDialog";
|
||||
import { getDefaultAppState } from "../appState";
|
||||
import { APP_NAME, TITLE_TIMEOUT } from "../constants";
|
||||
const languageDetector = new LanguageDetector();
|
||||
languageDetector.init({
|
||||
languageUtils: {
|
||||
formatLanguageCode: (langCode: Language["code"]) => langCode,
|
||||
isWhitelisted: () => true,
|
||||
},
|
||||
checkWhitelist: false,
|
||||
});
|
||||
|
||||
const excalidrawRef: React.MutableRefObject<
|
||||
MarkRequired<ExcalidrawAPIRefValue, "ready" | "readyPromise">
|
||||
|
@ -143,7 +162,6 @@ const initializeScene = async (opts: {
|
|||
// into the remote scene
|
||||
opts.resetScene();
|
||||
const scenePromise = opts.initializeSocketClient();
|
||||
trackEvent(EVENT_SHARE, "session join");
|
||||
|
||||
try {
|
||||
const [, roomId, roomKey] = getCollaborationLinkData(
|
||||
|
@ -182,6 +200,8 @@ const ExcalidrawWrapper = (props: { collab: CollabAPI }) => {
|
|||
height: window.innerHeight,
|
||||
});
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const currentLangCode = languageDetector.detect() || defaultLang.code;
|
||||
const [langCode, setLangCode] = useState(currentLangCode);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const onResize = () => {
|
||||
|
@ -209,12 +229,19 @@ const ExcalidrawWrapper = (props: { collab: CollabAPI }) => {
|
|||
const { collab } = props;
|
||||
|
||||
useEffect(() => {
|
||||
const storageSize = getTotalStorageSize();
|
||||
if (storageSize) {
|
||||
trackEvent(EVENT_LOAD, "storage", "size", storageSize);
|
||||
} else {
|
||||
trackEvent(EVENT_LOAD, "first time");
|
||||
}
|
||||
// delayed by 15 sec so that the app has a time to load the latest SW
|
||||
setTimeout(() => {
|
||||
const version = getVersion();
|
||||
const loggedVersion = window.localStorage.getItem(
|
||||
"excalidraw-lastLoggedVersion",
|
||||
);
|
||||
// prevent logging on multiple visits
|
||||
if (version && version !== loggedVersion) {
|
||||
window.localStorage.setItem("excalidraw-lastLoggedVersion", version);
|
||||
trackEvent("load", "version", version);
|
||||
}
|
||||
}, 15000);
|
||||
|
||||
excalidrawRef.current!.readyPromise.then((excalidrawApi) => {
|
||||
initializeScene({
|
||||
resetScene: excalidrawApi.resetScene,
|
||||
|
@ -256,6 +283,10 @@ const ExcalidrawWrapper = (props: { collab: CollabAPI }) => {
|
|||
};
|
||||
}, [collab.initializeSocketClient]);
|
||||
|
||||
useEffect(() => {
|
||||
languageDetector.cacheUserLanguage(langCode);
|
||||
}, [langCode]);
|
||||
|
||||
const onChange = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
|
@ -291,6 +322,32 @@ const ExcalidrawWrapper = (props: { collab: CollabAPI }) => {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
const renderFooter = useCallback(
|
||||
(isMobile: boolean) => {
|
||||
const renderLanguageList = () => (
|
||||
<LanguageList
|
||||
onChange={(langCode) => {
|
||||
setLangCode(langCode);
|
||||
}}
|
||||
languages={languages}
|
||||
floating={!isMobile}
|
||||
currentLangCode={langCode}
|
||||
/>
|
||||
);
|
||||
if (isMobile) {
|
||||
return (
|
||||
<fieldset>
|
||||
<legend>{t("labels.language")}</legend>
|
||||
{renderLanguageList()}
|
||||
</fieldset>
|
||||
);
|
||||
}
|
||||
return renderLanguageList();
|
||||
},
|
||||
[langCode],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Excalidraw
|
||||
|
@ -304,6 +361,8 @@ const ExcalidrawWrapper = (props: { collab: CollabAPI }) => {
|
|||
isCollaborating={collab.isCollaborating}
|
||||
onPointerUpdate={collab.onPointerUpdate}
|
||||
onExportToBackend={onExportToBackend}
|
||||
renderFooter={renderFooter}
|
||||
langCode={langCode}
|
||||
/>
|
||||
{errorMessage && (
|
||||
<ErrorDialog
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue