switch from connect to useSelector hook

This commit is contained in:
HF 2021-05-02 03:13:02 +02:00
parent c39bbbfa7b
commit 0ebc074086
11 changed files with 195 additions and 298 deletions

View File

@ -4,10 +4,10 @@
*/
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { useSelector, shallowEqual } from 'react-redux';
import { t } from 'ttag';
import type { State } from '../reducers';
import { getToday } from '../core/utils';
const keptState = {
coords: null,
@ -146,19 +146,10 @@ async function submitMakeMod(
}
function Admintools({
canvasId,
canvases,
userlvl,
}) {
const curDate = new Date();
let day = curDate.getDate();
let month = curDate.getMonth() + 1;
if (month < 10) month = `0${month}`;
if (day < 10) day = `0${day}`;
const maxDate = `${curDate.getFullYear()}-${month}-${day}`;
function Admintools() {
const maxDate = getToday();
const [selectedCanvas, selectCanvas] = useState(canvasId);
const [selectedCanvas, selectCanvas] = useState(0);
const [imageAction, selectImageAction] = useState('build');
const [iPAction, selectIPAction] = useState('ban');
const [protAction, selectProtAction] = useState('protect');
@ -173,6 +164,20 @@ function Admintools({
const [modlist, setModList] = useState([]);
const [submitting, setSubmitting] = useState(false);
const [
canvasId,
canvases,
userlvl,
] = useSelector((state) => [
state.canvas.canvasId,
state.canvas.canvases,
state.user.userlvl,
], shallowEqual);
useEffect(() => {
selectCanvas(canvasId);
}, [canvasId]);
let descAction;
switch (imageAction) {
case 'build':
@ -597,10 +602,4 @@ function Admintools({
);
}
function mapStateToProps(state: State) {
const { canvasId, canvases } = state.canvas;
const { userlvl } = state.user;
return { canvasId, canvases, userlvl };
}
export default connect(mapStateToProps)(Admintools);
export default React.memo(Admintools);

View File

@ -4,12 +4,11 @@
*/
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { useSelector, shallowEqual } from 'react-redux';
import fileDownload from 'js-file-download';
import { utils, applyPalette } from 'image-q';
import { jt, t } from 'ttag';
import type { State } from '../reducers';
import printGIMPPalette from '../core/exportGPL';
import { copyCanvasToClipboard } from '../utils/clipboard';
@ -208,12 +207,8 @@ async function renderOutputImage(opts) {
}
function Converter({
canvasId,
canvases,
showHiddenCanvases,
}) {
const [selectedCanvas, selectCanvas] = useState(canvasId);
function Converter() {
const [selectedCanvas, selectCanvas] = useState(0);
const [selectedFile, selectFile] = useState(null);
const [selectedStrategy, selectStrategy] = useState('nearest');
const [selectedColorDist, selectColorDist] = useState('euclidean');
@ -230,6 +225,21 @@ function Converter({
offsetX: 0,
offsetY: 0,
});
const [
canvasId,
canvases,
showHiddenCanvases,
] = useSelector((state) => [
state.canvas.canvasId,
state.canvas.canvases,
state.canvas.showHiddenCanvases,
], shallowEqual);
useEffect(() => {
selectCanvas(canvasId);
}, []);
const input = document.createElement('canvas');
useEffect(() => {
@ -615,13 +625,4 @@ function Converter({
);
}
function mapStateToProps(state: State) {
const {
canvasId,
canvases,
showHiddenCanvases,
} = state.canvas;
return { canvasId, canvases, showHiddenCanvases };
}
export default connect(mapStateToProps)(Converter);
export default React.memo(Converter);

View File

@ -4,26 +4,24 @@
*/
import React from 'react';
import { connect } from 'react-redux';
import { useSelector } from 'react-redux';
import {
durationToString,
} from '../core/utils';
import type { State } from '../reducers';
const CoolDownBox = ({ coolDown }) => (
<div
className={(coolDown && coolDown >= 300)
? 'cooldownbox show' : 'cooldownbox'}
>
{coolDown && durationToString(coolDown, true)}
</div>
);
const CoolDownBox = () => {
const coolDown = useSelector((state) => state.user.coolDown);
function mapStateToProps(state: State) {
const { coolDown } = state.user;
return { coolDown };
}
return (
<div
className={(coolDown && coolDown >= 300)
? 'cooldownbox show' : 'cooldownbox'}
>
{coolDown && durationToString(coolDown, true)}
</div>
);
};
export default connect(mapStateToProps)(CoolDownBox);
export default React.memo(CoolDownBox);

View File

@ -4,45 +4,38 @@
*/
import React from 'react';
import { connect } from 'react-redux';
import { useSelector, useDispatch } from 'react-redux';
import { t } from 'ttag';
import copy from '../utils/clipboard';
import { notify } from '../actions';
import type { State } from '../reducers';
function renderCoordinates(cell): string {
return `(${cell.join(', ')})`;
}
const CoordinatesBox = ({ view, hover, notifyCopy }) => (
<div
className="coorbox"
onClick={() => { copy(window.location.hash); notifyCopy(); }}
role="button"
title={t`Copy to Clipboard`}
tabIndex="0"
>{
renderCoordinates(hover
|| view.map(Math.round))
}</div>
);
const CoordinatesBox = () => {
const view = useSelector((state) => state.canvas.view);
const hover = useSelector((state) => state.gui.hover);
const dispatch = useDispatch();
function mapDispatchToProps(dispatch) {
return {
notifyCopy() {
dispatch(notify(t`Copied!`));
},
};
}
return (
<div
className="coorbox"
onClick={() => {
copy(window.location.hash);
dispatch(notify(t`Copied!`));
}}
role="button"
title={t`Copy to Clipboard`}
tabIndex="0"
>{
renderCoordinates(hover
|| view.map(Math.round))
}</div>
);
};
function mapStateToProps(state: State) {
const { view } = state.canvas;
const { hover } = state.gui;
return { view, hover };
}
export default connect(mapStateToProps, mapDispatchToProps)(CoordinatesBox);
export default React.memo(CoordinatesBox);

View File

@ -8,7 +8,7 @@ import React, {
import { useSelector, shallowEqual, useDispatch } from 'react-redux';
import { t } from 'ttag';
import { dateToString } from '../core/utils';
import { dateToString, getToday } from '../core/utils';
import { selectHistoricalTime } from '../actions';
import { requestHistoricalTimes } from '../actions/fetch';
@ -25,15 +25,6 @@ function stringToTime(timeString) {
return `${timeString.substr(0, 2)}:${timeString.substr(2, 2)}`;
}
function getToday() {
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}`;
return `${date.getFullYear()}-${month}-${day}`;
}
const HistorySelect = () => {
const dateSelect = useRef(null);

View File

@ -4,37 +4,40 @@
*/
import React from 'react';
import { connect } from 'react-redux';
import { useSelector, shallowEqual } from 'react-redux';
import { FaUser, FaPaintBrush } from 'react-icons/fa';
import { t } from 'ttag';
import { numberToString } from '../core/utils';
import type { State } from '../reducers';
const OnlineBox = () => {
const [
online,
totalPixels,
name,
] = useSelector((state) => [
state.ranks.online,
state.ranks.totalPixels,
state.user.name,
], shallowEqual);
return (
<div>
{(online || name)
? (
<div className="onlinebox">
{(online)
&& <span title={t`User online`}>{online} <FaUser />&nbsp;</span>}
{(name != null)
&& (
<span title={t`Pixels placed`}>
{numberToString(totalPixels)} <FaPaintBrush />
</span>
)}
</div>
) : null}
</div>
);
};
const OnlineBox = ({ online, totalPixels, name }) => (
<div>
{(online || name)
? (
<div className="onlinebox">
{(online)
&& <span title={t`User online`}>{online} <FaUser />&nbsp;</span>}
{(name != null)
&& (
<span title={t`Pixels placed`}>
{numberToString(totalPixels)} <FaPaintBrush />
</span>
)}
</div>
) : null}
</div>
);
function mapStateToProps(state: State) {
const { online, totalPixels } = state.ranks;
const { name } = state.user;
return { online, totalPixels, name };
}
export default connect(mapStateToProps)(OnlineBox);
export default React.memo(OnlineBox);

View File

@ -4,10 +4,9 @@
*/
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { selectColor } from '../actions';
import type { State } from '../reducers';
import useWindowSize from './hooks/resize';
@ -90,15 +89,22 @@ function getStylesByWindowSize(
}];
}
function Palette({
colors,
selectedColor,
paletteOpen,
compactPalette,
select,
clrIgnore,
}) {
const Palette = () => {
const [render, setRender] = useState(false);
const [
paletteOpen,
compactPalette,
colors,
clrIgnore,
selectedColor,
] = useSelector((state) => [
state.gui.paletteOpen,
state.gui.compactPalette,
state.canvas.palette.colors,
state.canvas.clrIgnore,
state.canvas.selectedColor,
], shallowEqual);
const dispatch = useDispatch();
useEffect(() => {
window.setTimeout(() => {
@ -139,32 +145,12 @@ function Palette({
? 'selected'
: 'unselected'}
color={color}
onClick={() => select(index + clrIgnore)}
onClick={() => dispatch(selectColor(index + clrIgnore))}
/>
))}
</div>
)
);
}
};
function mapStateToProps(state: State) {
const { paletteOpen, compactPalette } = state.gui;
const { palette, clrIgnore, selectedColor } = state.canvas;
return {
colors: palette.colors,
selectedColor,
paletteOpen,
compactPalette,
clrIgnore,
};
}
function mapDispatchToProps(dispatch) {
return {
select(color) {
dispatch(selectColor(color));
},
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Palette);
export default React.memo(Palette);

View File

@ -4,21 +4,13 @@
*/
import React from 'react';
import { connect } from 'react-redux';
import { useSelector } from 'react-redux';
import type { State } from '../reducers';
function Style({ style }) {
function Style() {
const style = useSelector((state) => state.gui.style);
const cssUri = window.ssv.availableStyles[style];
return (style === 'default') ? null
: (<link rel="stylesheet" type="text/css" href={cssUri} />);
}
function mapStateToProps(state: State) {
const {
style,
} = state.gui;
return { style };
}
export default connect(mapStateToProps)(Style);
export default React.memo(Style);

View File

@ -4,9 +4,8 @@
*/
import React from 'react';
import { connect } from 'react-redux';
import { useSelector, shallowEqual } from 'react-redux';
import type { State } from '../reducers';
import CoolDownBox from './CoolDownBox';
import NotifyBox from './NotifyBox';
import GlobeButton from './buttons/GlobeButton';
@ -25,13 +24,21 @@ const CONTEXT_MENUS = {
/* other context menus */
};
const UI = ({
isHistoricalView,
is3D,
isOnMobile,
menuOpen,
menuType,
}) => {
const UI = () => {
const [
isHistoricalView,
is3D,
isOnMobile,
menuOpen,
menuType,
] = useSelector((state) => [
state.canvas.isHistoricalView,
state.canvas.is3D,
state.user.isOnMobile,
state.contextMenu.menuOpen,
state.contextMenu.menuType,
], shallowEqual);
const contextMenu = (menuOpen && menuType) ? CONTEXT_MENUS[menuType] : null;
if (isHistoricalView) {
@ -52,25 +59,4 @@ const UI = ({
];
};
function mapStateToProps(state: State) {
const {
isHistoricalView,
is3D,
} = state.canvas;
const {
isOnMobile,
} = state.user;
const {
menuOpen,
menuType,
} = state.contextMenu;
return {
isHistoricalView,
is3D,
isOnMobile,
menuOpen,
menuType,
};
}
export default connect(mapStateToProps)(UI);
export default React.memo(UI);

View File

@ -4,7 +4,7 @@
*/
import React from 'react';
import { connect } from 'react-redux';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { c, t } from 'ttag';
import LanguageSelect from '../LanguageSelect';
@ -22,8 +22,6 @@ import {
selectStyle,
} from '../../actions';
import type { State } from '../../reducers';
const flexy = {
display: 'flex',
@ -97,28 +95,32 @@ const SettingsItem = ({
</div>
);
function Settings({
isMuted,
isGridShown,
isPixelNotifyShown,
isPotato,
isLightGrid,
isHistoricalView,
onMute,
autoZoomIn,
compactPalette,
selectedStyle,
onToggleGrid,
onTogglePixelNotify,
onToggleAutoZoomIn,
onToggleCompactPalette,
onToggleChatNotify,
onTogglePotatoMode,
onToggleLightGrid,
onToggleHistoricalView,
onSelectStyle,
chatNotify,
}) {
function Settings() {
const [
isGridShown,
isPixelNotifyShown,
autoZoomIn,
compactPalette,
isPotato,
isLightGrid,
selectedStyle,
isMuted,
chatNotify,
isHistoricalView,
] = useSelector((state) => [
state.gui.showGrid,
state.gui.showPixelNotify,
state.gui.autoZoomIn,
state.gui.compactPalette,
state.gui.isPotato,
state.gui.isLightGrid,
state.gui.style,
state.audio.mute,
state.audio.chatNotify,
state.canvas.isHistoricalView,
], shallowEqual);
const dispatch = useDispatch();
return (
<div style={{ paddingLeft: '5%', paddingRight: '5%', paddingTop: 30 }}>
<SettingsItem
@ -126,14 +128,14 @@ function Settings({
description={t`Turn on grid to highlight pixel borders.`}
keyBind={c('keybinds').t`G`}
value={isGridShown}
onToggle={onToggleGrid}
onToggle={() => dispatch(toggleGrid())}
/>
<SettingsItem
title={t`Show Pixel Activity`}
description={t`Show circles where pixels are placed.`}
keyBind={c('keybinds').t`X`}
value={isPixelNotifyShown}
onToggle={onTogglePixelNotify}
onToggle={() => dispatch(togglePixelNotify())}
/>
<SettingsItem
title={t`Disable Game Sounds`}
@ -141,39 +143,39 @@ function Settings({
description={t`All sound effects will be disabled.`}
keyBind={c('keybinds').t`M`}
value={isMuted}
onToggle={onMute}
onToggle={() => dispatch(toggleMute())}
/>
<SettingsItem
title={t`Enable chat notifications`}
description={t`Play a sound when new chat messages arrive`}
value={chatNotify}
onToggle={onToggleChatNotify}
onToggle={() => dispatch(toggleChatNotify())}
/>
<SettingsItem
title={t`Auto Zoom In`}
// eslint-disable-next-line max-len
description={t`Zoom in instead of placing a pixel when you tap the canvas and your zoom is small.`}
value={autoZoomIn}
onToggle={onToggleAutoZoomIn}
onToggle={() => dispatch(toggleAutoZoomIn())}
/>
<SettingsItem
title={t`Compact Palette`}
// eslint-disable-next-line max-len
description={t`Display Palette in a compact form that takes less screen space.`}
value={compactPalette}
onToggle={onToggleCompactPalette}
onToggle={() => dispatch(toggleCompactPalette())}
/>
<SettingsItem
title={t`Potato Mode`}
description={t`For when you are playing on a potato.`}
value={isPotato}
onToggle={onTogglePotatoMode}
onToggle={() => dispatch(togglePotatoMode())}
/>
<SettingsItem
title={t`Light Grid`}
description={t`Show Grid in white instead of black.`}
value={isLightGrid}
onToggle={onToggleLightGrid}
onToggle={() => dispatch(toggleLightGrid())}
/>
{(window.ssv && window.ssv.backupurl) && (
<SettingsItem
@ -181,7 +183,7 @@ function Settings({
description={t`Check out past versions of the canvas.`}
value={isHistoricalView}
keyBind={c('keybinds').t`H`}
onToggle={onToggleHistoricalView}
onToggle={() => dispatch(toggleHistoricalView())}
/>
)}
{(window.ssv && window.ssv.availableStyles) && (
@ -190,7 +192,7 @@ function Settings({
description={t`How pixelplanet should look like.`}
values={Object.keys(window.ssv.availableStyles)}
selected={selectedStyle}
onSelect={onSelectStyle}
onSelect={(style) => dispatch(selectStyle(style))}
/>
)}
{(window.ssv && navigator.cookieEnabled && window.ssv.langs) && (
@ -207,70 +209,4 @@ function Settings({
);
}
function mapStateToProps(state: State) {
const { mute, chatNotify } = state.audio;
const {
showGrid,
showPixelNotify,
autoZoomIn,
compactPalette,
isPotato,
isLightGrid,
style: selectedStyle,
} = state.gui;
const isMuted = mute;
const {
isHistoricalView,
} = state.canvas;
const isGridShown = showGrid;
const isPixelNotifyShown = showPixelNotify;
return {
isMuted,
isGridShown,
isPixelNotifyShown,
autoZoomIn,
compactPalette,
chatNotify,
isPotato,
isLightGrid,
isHistoricalView,
selectedStyle,
};
}
function mapDispatchToProps(dispatch) {
return {
onMute() {
dispatch(toggleMute());
},
onToggleGrid() {
dispatch(toggleGrid());
},
onTogglePixelNotify() {
dispatch(togglePixelNotify());
},
onToggleAutoZoomIn() {
dispatch(toggleAutoZoomIn());
},
onToggleCompactPalette() {
dispatch(toggleCompactPalette());
},
onToggleChatNotify() {
dispatch(toggleChatNotify());
},
onTogglePotatoMode() {
dispatch(togglePotatoMode());
},
onToggleLightGrid() {
dispatch(toggleLightGrid());
},
onToggleHistoricalView() {
dispatch(toggleHistoricalView());
},
onSelectStyle(style) {
dispatch(selectStyle(style));
},
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Settings);
export default React.memo(Settings);

View File

@ -46,6 +46,18 @@ export function dateToString(date: string) {
return date.substr(0, 4) + date.substr(5, 2) + date.substr(8, 2);
}
/*
* get current date in YYYY-MM-DD
*/
export function getToday() {
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}`;
return `${date.getFullYear()}-${month}-${day}`;
}
// z is assumed to be height here
// in ui and rendeer, y is height
export function getChunkOfPixel(