index.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import React from "react";
  2. import ReactDOM from "react-dom";
  3. import * as Sentry from "@sentry/browser";
  4. import * as SentryIntegrations from "@sentry/integrations";
  5. import { EVENT } from "./constants";
  6. import { TopErrorBoundary } from "./components/TopErrorBoundary";
  7. import { InitializeApp } from "./components/InitializeApp";
  8. import { IsMobileProvider } from "./is-mobile";
  9. import App from "./components/App";
  10. import { register as registerServiceWorker } from "./serviceWorker";
  11. import "./css/styles.scss";
  12. import { loadFromBlob } from "./data";
  13. // On Apple mobile devices add the proprietary app icon and splashscreen markup.
  14. // No one should have to do this manually, and eventually this annoyance will
  15. // go away once https://bugs.webkit.org/show_bug.cgi?id=183937 is fixed.
  16. if (
  17. /\b(iPad|iPhone|iPod)\b/.test(navigator.userAgent) &&
  18. !matchMedia("(display-mode: standalone)").matches
  19. ) {
  20. import(/* webpackChunkName: "pwacompat" */ "pwacompat");
  21. }
  22. const SentryEnvHostnameMap: { [key: string]: string } = {
  23. "excalidraw.com": "production",
  24. "vercel.app": "staging",
  25. };
  26. const REACT_APP_DISABLE_SENTRY =
  27. process.env.REACT_APP_DISABLE_SENTRY === "true";
  28. const REACT_APP_GIT_SHA = process.env.REACT_APP_GIT_SHA as string;
  29. // Disable Sentry locally or inside the Docker to avoid noise/respect privacy
  30. const onlineEnv =
  31. !REACT_APP_DISABLE_SENTRY &&
  32. Object.keys(SentryEnvHostnameMap).find(
  33. (item) => window.location.hostname.indexOf(item) >= 0,
  34. );
  35. Sentry.init({
  36. dsn: onlineEnv
  37. ? "https://7bfc596a5bf945eda6b660d3015a5460@sentry.io/5179260"
  38. : undefined,
  39. environment: onlineEnv ? SentryEnvHostnameMap[onlineEnv] : undefined,
  40. release: REACT_APP_GIT_SHA,
  41. ignoreErrors: [
  42. "undefined is not an object (evaluating 'window.__pad.performLoop')", // Only happens on Safari, but spams our servers. Doesn't break anything
  43. ],
  44. integrations: [
  45. new SentryIntegrations.CaptureConsole({
  46. levels: ["error"],
  47. }),
  48. ],
  49. beforeSend(event) {
  50. if (event.request?.url) {
  51. event.request.url = event.request.url.replace(/#.*$/, "");
  52. }
  53. return event;
  54. },
  55. });
  56. window.__EXCALIDRAW_SHA__ = REACT_APP_GIT_SHA;
  57. // Block pinch-zooming on iOS outside of the content area
  58. document.addEventListener(
  59. "touchmove",
  60. (event) => {
  61. // @ts-ignore
  62. if (event.scale !== 1) {
  63. event.preventDefault();
  64. }
  65. },
  66. { passive: false },
  67. );
  68. const rootElement = document.getElementById("root");
  69. ReactDOM.render(
  70. <TopErrorBoundary>
  71. <IsMobileProvider>
  72. <InitializeApp>
  73. <App />
  74. </InitializeApp>
  75. </IsMobileProvider>
  76. </TopErrorBoundary>,
  77. rootElement,
  78. );
  79. registerServiceWorker({
  80. onUpdate: (registration) => {
  81. const waitingServiceWorker = registration.waiting;
  82. if (waitingServiceWorker) {
  83. waitingServiceWorker.addEventListener(
  84. EVENT.STATE_CHANGE,
  85. (event: Event) => {
  86. const target = event.target as ServiceWorker;
  87. const state = target.state as ServiceWorkerState;
  88. if (state === "activated") {
  89. window.location.reload();
  90. }
  91. },
  92. );
  93. waitingServiceWorker.postMessage({ type: "SKIP_WAITING" });
  94. }
  95. },
  96. });
  97. if ("launchQueue" in window && "LaunchParams" in window) {
  98. (window as any).launchQueue.setConsumer(
  99. async (launchParams: { files: any[] }) => {
  100. if (!launchParams.files.length) {
  101. return;
  102. }
  103. const fileHandle = launchParams.files[0];
  104. const blob = await fileHandle.getFile();
  105. loadFromBlob(blob);
  106. },
  107. );
  108. }