mirror of
https://github.com/quantum5/qcal.git
synced 2025-04-24 17:51:57 -04:00
Implement state in URL
This commit is contained in:
parent
05236fff14
commit
d366604665
78
src/App.tsx
78
src/App.tsx
|
@ -1,16 +1,78 @@
|
|||
import React, {useState} from 'react';
|
||||
import React from 'react';
|
||||
import './App.css';
|
||||
import {Calendar} from './Calendar';
|
||||
import {gregorianJDN, Month} from "./dates";
|
||||
|
||||
function App() {
|
||||
type YearMonth = {
|
||||
year: number;
|
||||
month: Month;
|
||||
}
|
||||
|
||||
function parseURL(): YearMonth | null {
|
||||
const match = /\/(-?\d+)\/(\d+)/.exec(window.location.pathname);
|
||||
if (!match)
|
||||
return null;
|
||||
|
||||
const month = +match[2];
|
||||
if (month < 1 || month > 13)
|
||||
return null;
|
||||
return {year: +match[1], month: month as Month};
|
||||
}
|
||||
|
||||
type AppState = YearMonth & {
|
||||
todayJDN: number,
|
||||
};
|
||||
|
||||
class App extends React.Component<{}, AppState> {
|
||||
state: AppState;
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
const current = {year: 230, month: 5};
|
||||
const today = new Date();
|
||||
const todayJDN = gregorianJDN(today.getFullYear(), today.getMonth() + 1, today.getDay());
|
||||
const [yearMonth, setYearMonth] = useState([230, 5]);
|
||||
return (
|
||||
<Calendar year={yearMonth[0]} month={yearMonth[1] as Month} todayJDN={todayJDN}
|
||||
onSwitch={(year, month) => setYearMonth([year, month])}/>
|
||||
);
|
||||
|
||||
this.state = {
|
||||
...(parseURL() || current as YearMonth),
|
||||
todayJDN: gregorianJDN(today.getFullYear(), today.getMonth() + 1, today.getDay()),
|
||||
};
|
||||
this.updateURL();
|
||||
this.updateStateFromURL = this.updateStateFromURL.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('popstate', this.updateStateFromURL);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('popstate', this.updateStateFromURL);
|
||||
}
|
||||
|
||||
private updateStateFromURL(event: PopStateEvent) {
|
||||
this.setState(event.state);
|
||||
}
|
||||
|
||||
private updateURL() {
|
||||
const {year, month} = this.state;
|
||||
const path = `/${year}/${month}`;
|
||||
if (path !== window.location.pathname) {
|
||||
window.history.pushState({year, month}, '', path);
|
||||
}
|
||||
}
|
||||
|
||||
setState(state: any, callback?: () => void) {
|
||||
super.setState(state, () => {
|
||||
this.updateURL();
|
||||
callback && callback();
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return <Calendar
|
||||
year={this.state.year} month={this.state.month} todayJDN={this.state.todayJDN}
|
||||
onSwitch={(year, month) => {
|
||||
this.setState({year, month})
|
||||
}}/>;
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
Loading…
Reference in a new issue