Left file: appwork-v1_4_0/react-starter/src/shared/Router.js  
Right file: appwork-v1_5_0/react-starter/src/shared/Router.js  
1 import React, { Component } from 'react' = 1 import React, { Component } from 'react'
2 import { BrowserRouter as AppRouter, Route, Switch, Redirect } from 'react-router-dom'   2 import { BrowserRouter as AppRouter, Route, Switch, Redirect } from 'react-router-dom'
3 import NotFound from './NotFound'   3 import NotFound from './NotFound'
4     4  
5 // Routes   5 // Routes
6 import { DefaultLayout, titleTemplate, defaultRoute, routes } from '../routes'   6 import { DefaultLayout, titleTemplate, defaultRoute, routes } from '../routes'
7     7  
8 // ---   8 // ---
9 // Main route component   9 // Main route component
10     10  
11 class Router extends Component {   11 class Router extends Component {
12   constructor(props) {   12   constructor(props) {
13     super(props)   13     super(props)
14     14  
15     // Set default layout   15     // Set default layout
16     this.routes = routes.map(route => {   16     this.routes = routes.map(route => {
17       route.layout = route.layout || DefaultLayout   17       route.layout = route.layout || DefaultLayout
18       route.exact = typeof route.exact === 'undefined' ? true : route.exact   18       route.exact = typeof route.exact === 'undefined' ? true : route.exact
19       return route   19       return route
20     })   20     })
21     21  
22     // Set app loading class   22     // Set app loading class
23     document.documentElement.classList.add('app-loading')   23     document.documentElement.classList.add('app-loading')
24   }   24   }
25     25  
26   componentDidMount() {   26   componentDidMount() {
27     const removeLoadingClass = () => {   27     const removeLoadingClass = () => {
28       document.documentElement.classList.remove('app-loading')   28       document.documentElement.classList.remove('app-loading')
29     }   29     }
30     30  
31     // Remove splash screen   31     // Remove splash screen
32     const splashScreen = document.querySelector('.app-splash-screen')   32     const splashScreen = document.querySelector('.app-splash-screen')
33     if (splashScreen) {   33     if (splashScreen) {
34       splashScreen.style.opacity = 0   34       splashScreen.style.opacity = 0
35       setTimeout(() => {   35       setTimeout(() => {
    <> 36         if (splashScreen && splashScreen.parentNode) {
36         splashScreen && splashScreen.parentNode.removeChild(splashScreen)   37           splashScreen.parentNode.removeChild(splashScreen)
      38         }
37         removeLoadingClass() = 39         removeLoadingClass()
38       }, 300)   40       }, 300)
39     } else {   41     } else {
40       removeLoadingClass()   42       removeLoadingClass()
41     }   43     }
42   }   44   }
43     45  
44   setTitle(title) {   46   setTitle(title) {
45     document.title = titleTemplate.replace('%s', title)   47     document.title = titleTemplate.replace('%s', title)
46   }   48   }
47     49  
48   scrollTop(to, duration, element = document.scrollingElement || document.documentElement) {   50   scrollTop(to, duration, element = document.scrollingElement || document.documentElement) {
49     if (element.scrollTop === to) return   51     if (element.scrollTop === to) return
50     const start = element.scrollTop   52     const start = element.scrollTop
51     const change = to - start   53     const change = to - start
52     const startDate = +new Date()   54     const startDate = +new Date()
53     55  
54     if (!duration) {   56     if (!duration) {
55       element.scrollTop = to   57       element.scrollTop = to
56       return   58       return
57     }   59     }
58     60  
59     // t = current time; b = start value; c = change in value; d = duration   61     // t = current time; b = start value; c = change in value; d = duration
60     const easeInOutQuad = (t, b, c, d) => {   62     const easeInOutQuad = (t, b, c, d) => {
61       t /= d / 2   63       t /= d / 2
62       if (t < 1) return c / 2 * t * t + b   64       if (t < 1) return c / 2 * t * t + b
63       t--   65       t--
64       return -c / 2 * (t * (t - 2) - 1) + b   66       return -c / 2 * (t * (t - 2) - 1) + b
65     }   67     }
66     68  
67     const animateScroll = () => {   69     const animateScroll = () => {
68       const currentDate = +new Date()   70       const currentDate = +new Date()
69       const currentTime = currentDate - startDate   71       const currentTime = currentDate - startDate
70       element.scrollTop = parseInt(easeInOutQuad(currentTime, start, change, duration))   72       element.scrollTop = parseInt(easeInOutQuad(currentTime, start, change, duration))
71       if (currentTime < duration) {   73       if (currentTime < duration) {
72         requestAnimationFrame(animateScroll)   74         requestAnimationFrame(animateScroll)
73       } else {   75       } else {
74         element.scrollTop = to   76         element.scrollTop = to
75       }   77       }
76     }   78     }
77     79  
78     animateScroll()   80     animateScroll()
79   }   81   }
80     82  
81   render() {   83   render() {
82     return (   84     return (
83       <AppRouter basename={process.env.REACT_APP_BASENAME}>   85       <AppRouter basename={process.env.REACT_APP_BASENAME}>
84         <Switch>   86         <Switch>
85           {this.routes.map(route => (   87           {this.routes.map(route => (
86             <Route   88             <Route
87               path={route.path}   89               path={route.path}
88               exact={route.exact}   90               exact={route.exact}
89               render={props => {   91               render={props => {
90                 // On small screens collapse sidenav   92                 // On small screens collapse sidenav
91                 if (window.layoutHelpers && window.layoutHelpers.isSmallScreen()) {   93                 if (window.layoutHelpers && window.layoutHelpers.isSmallScreen()) {
92                   window.layoutHelpers.setCollapsed(true, false)   94                   window.layoutHelpers.setCollapsed(true, false)
93                 }   95                 }
94     96  
95                 // Scroll page to top on route render   97                 // Scroll page to top on route render
96                 this.scrollTop(0, 0)   98                 this.scrollTop(0, 0)
97     99  
98                 // Return layout   100                 // Return layout
99                 return <route.layout {...props}>   101                 return <route.layout {...props}>
100                   <route.component {...props} setTitle={this.setTitle} scrollTop={this.scrollTop} />   102                   <route.component {...props} setTitle={this.setTitle} scrollTop={this.scrollTop} />
101                 </route.layout>   103                 </route.layout>
102               }}   104               }}
103               key={route.path}   105               key={route.path}
104             />   106             />
105           ))}   107           ))}
106           {defaultRoute !== '/' && <Redirect from="/" to={defaultRoute} exact={true} />}   108           {defaultRoute !== '/' && <Redirect from="/" to={defaultRoute} exact={true} />}
107     109  
108           {/* NotFound page */}   110           {/* NotFound page */}
109           <Route path="*" component={NotFound} />   111           <Route path="*" component={NotFound} />
110         </Switch>   112         </Switch>
111       </AppRouter>   113       </AppRouter>
112     )   114     )
113   }   115   }
114 }   116 }
115     117  
116 export default Router   118 export default Router