add HistorySelection dialog

This commit is contained in:
HF 2020-01-09 21:32:37 +01:00
parent 2ecf670db7
commit 1e1d511d21
8 changed files with 231 additions and 17 deletions

View File

@ -35,6 +35,12 @@ export function toggleChatBox(): Action {
};
}
export function toggleHistoricalView(): Action {
return {
type: 'TOGGLE_HISTORICAL_VIEW',
};
}
export function toggleGrid(): Action {
return {
type: 'TOGGLE_GRID',

View File

@ -24,6 +24,7 @@ export type Action =
| { type: 'TOGGLE_POTATO_MODE' }
| { type: 'TOGGLE_LIGHT_GRID' }
| { type: 'TOGGLE_OPEN_MENU' }
| { type: 'TOGGLE_HISTORICAL_VIEW' }
| { type: 'SET_NOTIFICATION', notification: string }
| { type: 'UNSET_NOTIFICATION' }
| { type: 'SET_PLACE_ALLOWED', placeAllowed: boolean }

View File

@ -4,8 +4,10 @@
*/
import React from 'react';
import { connect } from 'react-redux';
import { IconContext } from 'react-icons';
import type { State } from '../reducers';
import CoolDownBox from './CoolDownBox';
import NotifyBox from './NotifyBox';
import CoordinatesBox from './CoordinatesBox';
@ -20,31 +22,49 @@ import Menu from './Menu';
import ReCaptcha from './ReCaptcha';
import ExpandMenuButton from './ExpandMenuButton';
import ModalRoot from './ModalRoot';
import HistorySelect from './HistorySelect';
import baseCss from './base.tcss';
const App = () => (
const App = ({ isHistoricalView }) => (
<div>
<style dangerouslySetInnerHTML={{ __html: baseCss }} />
<canvas id="gameWindow" />
<div id="outstreamContainer" />
<ReCaptcha />
<IconContext.Provider value={{ style: { verticalAlign: 'middle' } }}>
<CoolDownBox />
<NotifyBox />
<Menu />
<GlobeButton />
<CanvasSwitchButton />
<PalselButton />
<Menu />
<ChatButton />
<Palette />
<ChatBox />
<OnlineBox />
<CoordinatesBox />
<ExpandMenuButton />
{
(isHistoricalView)
? <HistorySelect />
: (
<div>
<PalselButton />
<Palette />
<GlobeButton />
<CoolDownBox />
<NotifyBox />
</div>
)
}
<ModalRoot />
</IconContext.Provider>
</div>
);
export default App;
function mapStateToProps(state: State) {
const {
isHistoricalView,
} = state.canvas;
return {
isHistoricalView,
};
}
export default connect(mapStateToProps)(App);

View File

@ -0,0 +1,128 @@
/*
* LogIn Form
* @flow
*/
import React from 'react';
import { connect } from 'react-redux';
import type { State } from '../reducers';
function dateToString(date) {
const timeString = date.substr(0, 4) + date.substr(5, 2) + date.substr(8, 2);
return timeString;
}
async function getTimes(day, canvasId) {
try {
const response = await fetch(`./api/history?day=${day}&id=${canvasId}`);
if (response.status !== 200) {
return [];
}
const times = await response.json();
const parsedTimes = times.map((a) => `${a.substr(0, 2)}:${a.substr(-2, 2)}`);
return parsedTimes;
} catch {
return [];
}
}
class HistorySelect extends React.Component {
constructor() {
super();
const date = new Date();
let day = date.getDate();
let month = date.getMonth() + 1;
if (month < 10) month = `0${month}`;
if (day < 10) day = `0${day}`;
const max = `${date.getFullYear()}-${month}-${day}`;
this.state = {
submitting: false,
selectedDate: new Date(),
max,
};
this.handleDateChange = this.handleDateChange.bind(this);
}
async handleDateChange(evt) {
const {
submitting,
} = this.state;
if (submitting) {
return;
}
this.setState({
submitting: true,
});
const {
canvasId,
} = this.props;
const date = dateToString(evt.target.value)
const times = await getTimes(date, canvasId);
this.setState({
submitting: false,
selectedDate: date,
times,
});
}
render() {
const {
setTime,
} = this.props;
const {
submitting,
times,
selectedDate,
max,
} = this.state;
return (
<div id="historyselect">
<input
type="date"
requiredPattern="\d{4}-\d{2}-\d{2}"
min="2020-01-08"
max={max}
onChange={this.handleDateChange}
/>
<div>
{ (times && times.length > 0)
? (
<select onChange={(evt) => setTime(selectedDate, evt.target.value)}>
{times.map((value) => (
<option value={value}>{value}</option>
))}
</select>
)
: <p>Select Date</p> }
{ (submitting) ? <p>Loading...</p> : null }
</div>
</div>
);
}
}
function mapDispatchToProps(dispatch) {
return {
setTime(date: string, time: string) {
const timeString = time.substr(0, 2) + time.substr(-2, 2);
const dateString = dateToString(date);
console.log(`${timeString} - ${dateString}`);
// dispatch(selectHistoricalTime(dateString, timeString));
},
};
}
function mapStateToProps(state: State) {
const {
canvasId,
} = state.canvas;
return { canvasId };
}
export default connect(mapStateToProps, mapDispatchToProps)(HistorySelect);

View File

@ -17,6 +17,7 @@ import {
toggleChatNotify,
togglePotatoMode,
toggleLightGrid,
toggleHistoricalView,
} from '../actions';
import type { State } from '../reducers';
@ -94,6 +95,7 @@ function SettingsModal({
isPixelNotifyShown,
isPotato,
isLightGrid,
isHistoricalView,
onMute,
autoZoomIn,
compactPalette,
@ -104,6 +106,7 @@ function SettingsModal({
onToggleChatNotify,
onTogglePotatoMode,
onToggleLightGrid,
onToggleHistoricalView,
chatNotify,
}) {
return (
@ -159,6 +162,15 @@ function SettingsModal({
value={isLightGrid}
onToggle={onToggleLightGrid}
/>
{ (window.backupurl)
? (
<SettingsItem
title="Historical View"
description="Check out past versions of the canvas."
value={isHistoricalView}
onToggle={onToggleHistoricalView}
/>
) : null }
</Modal>
);
}
@ -174,6 +186,9 @@ function mapStateToProps(state: State) {
isLightGrid,
} = state.gui;
const isMuted = mute;
const {
isHistoricalView,
} = state.canvas;
const isGridShown = showGrid;
const isPixelNotifyShown = showPixelNotify;
return {
@ -185,6 +200,7 @@ function mapStateToProps(state: State) {
chatNotify,
isPotato,
isLightGrid,
isHistoricalView,
};
}
@ -214,6 +230,9 @@ function mapDispatchToProps(dispatch) {
onToggleLightGrid() {
dispatch(toggleLightGrid());
},
onToggleHistoricalView() {
dispatch(toggleHistoricalView());
},
};
}

View File

@ -150,11 +150,11 @@ kbd {
top: 139px;
}
:global(#globebutton) {
left: 57px;
left: 98px;
top: 16px;
}
:global(#canvasbutton) {
left: 98px;
left: 57px;
top: 16px;
}
:global(#minecrafttpbutton) {
@ -170,6 +170,27 @@ kbd {
right: 57px;
}
:global(#historyselect) {
position: absolute;
top: 16px;
left: 0px;
right: 0px;
height: 70px;
width: 140px;
background-color: rgba(226, 226, 226, 0.80);
color: black;
font-size: 14px;
line-height: 30px;
text-align: center;
vertical-align: middle;
border: solid black;
border-width: thin;
padding: 0 24px;
margin-left: auto;
margin-right: auto;
z-index: 2;
}
:global(.Modal) {
position: absolute;
top: 50%;

View File

@ -26,7 +26,6 @@ export type CanvasState = {
canvasIdent: string,
canvasSize: number,
canvasMaxTiledZoom: number,
minScale: number,
palette: Palette,
chunks: Map<string, ChunkRGB>,
view: Cell,
@ -34,6 +33,7 @@ export type CanvasState = {
viewscale: number,
requested: Set<string>,
fetchs: number,
isHistoricalView: boolean,
// object with all canvas informations from all canvases like colors and size
canvases: Object,
};
@ -107,6 +107,7 @@ const initialState: CanvasState = {
...getViewFromURL(DEFAULT_CANVASES),
requested: new Set(),
fetchs: 0,
isHistoricalView: false,
};
@ -141,12 +142,20 @@ export default function gui(
}
case 'SET_SCALE': {
let { view, viewscale } = state;
const { canvasSize } = state;
let {
view,
viewscale,
} = state;
const {
canvasSize,
isHistoricalView,
} = state;
let [hx, hy] = view;
let { scale } = action;
const { zoompoint } = action;
scale = clamp(scale, TILE_SIZE / canvasSize, MAX_SCALE);
const minScale = (isHistoricalView) ? 0.7 : TILE_SIZE / canvasSize;
scale = clamp(scale, minScale, MAX_SCALE);
if (zoompoint) {
let scalediff = viewscale;
// clamp to 1.0 (just do this when zoompoint is given, or it would mess with phones)
@ -171,6 +180,15 @@ export default function gui(
};
}
case 'TOGGLE_HISTORICAL_VIEW': {
return {
...state,
scale: 1.0,
viewscale: 1.0,
isHistoricalView: !state.isHistoricalView,
};
}
case 'SET_VIEW_COORDINATES': {
const { view } = action;
const { canvasSize } = state;
@ -186,7 +204,7 @@ export default function gui(
case 'RELOAD_URL': {
const { canvasId, chunks, canvases } = state;
const nextstate = getViewFromURL(canvases);
if (nextstate.canvasId != canvasId) {
if (nextstate.canvasId !== canvasId) {
chunks.clear();
}
return {
@ -205,7 +223,7 @@ export default function gui(
y = Math.round(y);
const scale = Math.round(Math.log2(viewscale) * 10);
const newhash = `#${canvasIdent},${x},${y},${scale}`;
history.replaceState(undefined, undefined, newhash);
window.history.replaceState(undefined, undefined, newhash);
return {
...state,
};
@ -316,7 +334,7 @@ export default function gui(
const canvasSize = canvases[canvasId].size;
const canvasMaxTiledZoom = getMaxTiledZoom(canvasSize);
const palette = new Palette(canvas.colors, 0);
const view = (canvasId == 0) ? getGivenCoords() : [0, 0];
const view = (canvasId === 0) ? getGivenCoords() : [0, 0];
chunks.clear();
return {
...state,

View File

@ -28,6 +28,7 @@ export default (store) => (next) => (action) => {
break;
}
case 'TOGGLE_HISTORICAL_VIEW':
case 'SET_SCALE': {
const {
viewscale,