import React from 'react'; import { combineReducers, createStore, applyMiddleware, compose } from 'redux'; import reduceReducers from 'reduce-reducers'; import thunk from 'redux-thunk'; import { Provider } from 'react-redux'; import { render } from 'react-dom'; import { ApplicationBase } from '@jho406/breezy'; import { persistStore, persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; import { applicationRootReducer, applicationPagesReducer } from './reducer'; import { buildVisitAndRemote } from './application_visit';

// Mapping between your props template to Component, you must add to this // to register any new page level component you create. If you are using the // scaffold, it will auto append the identifers for you. // // e.g {'posts/new': PostNew} const identifierToComponentMapping = { };

if (typeof window !== “undefined”) {

document.addEventListener("DOMContentLoaded", function () {
  const appEl = document.getElementById("app");
  const location = window.location;

  if (appEl) {
    render(
      <Application
        appEl={appEl}
        // The base url prefixed to all calls made by the `visit`
        // and `remote` thunks.
        baseUrl={location.origin}
        // The global var BREEZY_INITIAL_PAGE_STATE is set by your erb
        // template, e.g., index.html.erb
        initialPage={window.BREEZY_INITIAL_PAGE_STATE}
        // The initial path of the page, e.g., /foobar
        path={location.pathname + location.search + location.hash}
        buildVisitAndRemote={buildVisitAndRemote}
      />,
      appEl
    );
  }
});

}

export default class Application extends ApplicationBase {

mapping() {
  return identifierToComponentMapping;
}

visitAndRemote(navRef, store) {
  return buildVisitAndRemote(navRef, store);
}

buildStore(initialState, { breezy: breezyReducer, pages: pagesReducer }) {
  // Create the store
  // See `./reducer.js` for an explaination of the two included reducers
  const composeEnhancers =
    (this.hasWindow && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
    compose;
  const reducer = this.wrapWithPersistReducer(
    reduceReducers(
      combineReducers({
        breezy: breezyReducer,
        pages: reduceReducers(pagesReducer, applicationPagesReducer),
      }),
      applicationRootReducer
    )
  );
  const store = createStore(
    reducer,
    initialState,
    composeEnhancers(applyMiddleware(thunk))
  );

  if (this.hasWindow) {
    // Persist the store using Redux-Persist
    persistStore(store);
  }

  return store;
}

wrapWithPersistReducer(reducers) {
  // Redux Persist settings
  // The key is set to the stringified JS asset path to remove the need for
  // migrations when hydrating.
  if (!this.hasWindow) {
    return reducers;
  }
  const prefix = "breezy";
  const persistKey =
    prefix +
    this.props.initialPage.assets
      .filter((asset) => asset.endsWith(".js"))
      .join(",");
  const persistConfig = {
    key: persistKey,
    storage,
  };

  // Remove older storage items that were used by previous JS assets
  if (this.hasWindow) {
    const storedKeys = Object.keys(localStorage);
    storedKeys.forEach((key) => {
      if (key.startsWith(`persist:${prefix}`) && key !== persistKey) {
        localStorage.removeItem(key);
      }
    });
  }

  return persistReducer(persistConfig, reducers);
}

}