production-taskbar-client / src / renderer / index.jsx
index.jsx
Raw
/* eslint-disable no-use-before-define */
import React from "react";
import log from "electron-log/renderer";
import { ipcRenderer } from "electron";
import { createRoot } from "react-dom/client";
import { Provider as ReactProvider } from "react-redux";
import { Provider as RxDBProvider } from "rxdb-hooks";
import getDatabase from "./app/local_storage/rxdb";
import App from "./app/App";
import store from "./app/store/store";
import configureRootDocument from "../main/utils/configureRootDocument";

import "./app/locale/i18n";

configureRootDocument();

window.onerror = (errorMsg, url, lineNumber, columnNumber, error) => {
  log.error(
    `${url} on line ${lineNumber} col ${columnNumber}: ${errorMsg}\n${error?.stack}`
  );
  ipcRenderer.invoke("main", {
    event: "sendmail-admin",
    payload: error,
  });
};

const start = () =>
  getDatabase()
    .then((db) => renderWithDB(db)) // Normal start of App
    .catch((e) => {
      log.error(`getDatabase error:\n${e}`);
      deleteDatabases(); // Handle database lock due wrong env RXDB_PASSWORD by deleting and recreating new IndexDB
    });

const renderWithDB = (db) => {
  const container = document.getElementById("root");
  const root = createRoot(container);
  return root.render(
    <RxDBProvider db={db}>
      <ReactProvider store={store}>
        <App />
      </ReactProvider>
    </RxDBProvider>
  );
};

// Delete all IndexDB databases and set onSuccess event to start() render again.
const deleteDatabases = async () => {
  try {
    const databases = await indexedDB.databases();
    databases.forEach((db, index, array) => {
      const request = indexedDB.deleteDatabase(db.name);
      if (index === array.length - 1) {
        request.onsuccess = () => {
          log.info("reload window on success indexedDB.deleteDatabase()");
          setTimeout(() => window.location.reload(), 1000);
        };
      }
    });
  } catch (e) {
    ipcRenderer
      .invoke("main", { event: "delete-db" })
      .then(({ result, error }) => {
        if (result === "success") {
          log.info("reload window on success rm database dir");
          setTimeout(() => window.location.reload(), 1000);
          return;
        }
        log.error(`${JSON.stringify(error)}\nCorrupted db, deletion failed.`);
        throw new Error(result);
      })
      .catch(async (error) => {
        log.error(
          `Fatal error on indexedDB.deleteDatabases, force clear database and restart via cmd. ${error}`
        );
        ipcRenderer.invoke("main", {
          event: "prune-db-and-restart",
        });
      });
  }
};

// Entry point
start();