reorganize store

This commit is contained in:
HF 2022-07-11 14:42:09 +02:00
parent 4612384a7d
commit 2789cd2a54
71 changed files with 123 additions and 160 deletions

View File

@ -17,7 +17,7 @@ import {
removeChatChannel,
setMobile,
windowResize,
} from './actions';
} from './store/actions';
import {
receivePixelUpdate,
receivePixelReturn,

View File

@ -7,7 +7,7 @@ import React, { useState, useEffect, useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import GlobalCaptcha from './GlobalCaptcha';
import { closeAlert } from '../actions';
import { closeAlert } from '../store/actions';
const Alert = () => {
const [render, setRender] = useState(false);

View File

@ -9,7 +9,7 @@ import { t } from 'ttag';
import {
validateEMail, validatePassword,
} from '../utils/validation';
import { requestMailChange } from '../actions/fetch';
import { requestMailChange } from '../store/actions/fetch';
function validate(email, password) {
const errors = [];

View File

@ -8,8 +8,8 @@ import { t } from 'ttag';
import { useDispatch } from 'react-redux';
import { validateName } from '../utils/validation';
import { requestNameChange } from '../actions/fetch';
import { setName } from '../actions';
import { requestNameChange } from '../store/actions/fetch';
import { setName } from '../store/actions';
function validate(name) {

View File

@ -7,9 +7,9 @@ import React, { useState } from 'react';
import { t } from 'ttag';
import { useSelector, useDispatch } from 'react-redux';
import { setMailreg } from '../actions';
import { setMailreg } from '../store/actions';
import { validatePassword } from '../utils/validation';
import { requestPasswordChange } from '../actions/fetch';
import { requestPasswordChange } from '../store/actions/fetch';
function validate(mailreg, password, newPassword, confirmPassword) {
const errors = [];

View File

@ -5,7 +5,7 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { showContextMenu } from '../actions';
import { showContextMenu } from '../store/actions';
import { MarkdownParagraph } from './Markdown';
import {
colorFromText,

View File

@ -8,7 +8,7 @@ import { useSelector, useDispatch } from 'react-redux';
import { t } from 'ttag';
import copy from '../utils/clipboard';
import { notify } from '../actions';
import { notify } from '../store/actions';
function renderCoordinates(cell): string {

View File

@ -8,8 +8,8 @@ import { useDispatch } from 'react-redux';
import { t } from 'ttag';
import { validatePassword } from '../utils/validation';
import { requestDeleteAccount } from '../actions/fetch';
import { logoutUser } from '../actions';
import { requestDeleteAccount } from '../store/actions/fetch';
import { logoutUser } from '../store/actions';
function validate(password) {
const errors = [];

View File

@ -8,7 +8,7 @@ import React, { useState } from 'react';
import { t } from 'ttag';
import Captcha from './Captcha';
import { requestSolveCaptcha } from '../actions/fetch';
import { requestSolveCaptcha } from '../store/actions/fetch';
const GlobalCaptcha = ({ close }) => {
const [errors, setErrors] = useState([]);

View File

@ -9,8 +9,8 @@ import { useSelector, shallowEqual, useDispatch } from 'react-redux';
import { t } from 'ttag';
import { dateToString, getToday } from '../core/utils';
import { selectHistoricalTime } from '../actions';
import { requestHistoricalTimes } from '../actions/fetch';
import { selectHistoricalTime } from '../store/actions';
import { requestHistoricalTimes } from '../store/actions/fetch';
function stringToDate(dateString) {

View File

@ -6,7 +6,7 @@ import { useDispatch } from 'react-redux';
import { t } from 'ttag';
import LogInForm from './LogInForm';
import { changeWindowType } from '../actions';
import { changeWindowType } from '../store/actions';
const logoStyle = {
marginRight: 5,

View File

@ -9,8 +9,8 @@ import { t } from 'ttag';
import {
validateEMail, validateName, validatePassword,
} from '../utils/validation';
import { requestLogin } from '../actions/fetch';
import { loginUser } from '../actions';
import { requestLogin } from '../store/actions/fetch';
import { loginUser } from '../store/actions';
function validate(nameoremail, password) {

View File

@ -14,7 +14,7 @@ import {
closeWindow,
restoreWindow,
removeWindow,
} from '../actions';
} from '../store/actions';
import COMPONENTS from './windows';
const ModalRoot = () => {

View File

@ -8,7 +8,7 @@ import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { FaUser, FaPaintBrush, FaFlipboard } from 'react-icons/fa';
import { t } from 'ttag';
import { toggleOnlineCanvas } from '../actions';
import { toggleOnlineCanvas } from '../store/actions';
import { numberToString } from '../core/utils';

View File

@ -6,7 +6,7 @@
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { selectColor } from '../actions';
import { selectColor } from '../store/actions';
import useWindowSize from './hooks/resize';

View File

@ -10,7 +10,7 @@ import { t } from 'ttag';
import {
setBlockingDm,
setUserBlock,
} from '../actions';
} from '../store/actions';
import MdToggleButton from './MdToggleButton';
const SocialSettings = ({ done }) => {

View File

@ -13,8 +13,8 @@ import ChangeName from './ChangeName';
import ChangeMail from './ChangeMail';
import DeleteAccount from './DeleteAccount';
import SocialSettings from './SocialSettings';
import { logoutUser } from '../actions';
import { requestLogOut } from '../actions/fetch';
import { logoutUser } from '../store/actions';
import { requestLogOut } from '../store/actions/fetch';
import { numberToString } from '../core/utils';

View File

@ -6,7 +6,7 @@ import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { t } from 'ttag';
import { requestResendVerify } from '../actions/fetch';
import { requestResendVerify } from '../store/actions/fetch';
const UserMessages = () => {

View File

@ -17,7 +17,7 @@ import {
maximizeWindow,
cloneWindow,
focusWindow,
} from '../actions';
} from '../store/actions';
import useDrag from './hooks/drag';
import COMPONENTS from './windows';
@ -153,7 +153,7 @@ const Window = ({ id }) => {
>
</div>
<div
<div
className="win-content"
key="content"
>

View File

@ -7,7 +7,7 @@ import { useDispatch } from 'react-redux';
import { FaFlipboard } from 'react-icons/fa';
import { t } from 'ttag';
import { showCanvasSelectionModal } from '../../actions';
import { showCanvasSelectionModal } from '../../store/actions';
const CanvasSwitchButton = () => {

View File

@ -13,7 +13,7 @@ import { t } from 'ttag';
import {
hideAllWindowTypes,
openChatWindow,
} from '../../actions';
} from '../../store/actions';
/*
* return [ showWindows, chatOpen, chatHiden ]

View File

@ -9,7 +9,7 @@ import { useSelector, useDispatch } from 'react-redux';
import { MdExpandMore, MdExpandLess } from 'react-icons/md';
import { t } from 'ttag';
import { toggleOpenMenu } from '../../actions';
import { toggleOpenMenu } from '../../store/actions';
const ExpandMenuButton = () => {
const menuOpen = useSelector((state) => state.gui.menuOpen);

View File

@ -8,7 +8,7 @@ import { useDispatch } from 'react-redux';
import { FaQuestion } from 'react-icons/fa';
import { t } from 'ttag';
import { showHelpModal } from '../../actions';
import { showHelpModal } from '../../store/actions';
const HelpButton = () => {

View File

@ -8,7 +8,7 @@ import { useDispatch } from 'react-redux';
import { MdPerson } from 'react-icons/md';
import { t } from 'ttag';
import { showUserAreaModal } from '../../actions';
import { showUserAreaModal } from '../../store/actions';
const LogInButton = () => {

View File

@ -9,7 +9,7 @@ import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { MdPalette } from 'react-icons/md';
import { t } from 'ttag';
import { toggleOpenPalette } from '../../actions';
import { toggleOpenPalette } from '../../store/actions';
const PalselButton = () => {
const paletteOpen = useSelector((state) => state.gui.paletteOpen);

View File

@ -8,7 +8,7 @@ import { useDispatch } from 'react-redux';
import { FaCog } from 'react-icons/fa';
import { t } from 'ttag';
import { showSettingsModal } from '../../actions';
import { showSettingsModal } from '../../store/actions';
const SettingsButton = () => {

View File

@ -15,7 +15,7 @@ import {
setLeaveChannel,
muteChatChannel,
unmuteChatChannel,
} from '../../actions';
} from '../../store/actions';
const ChannelContextMenu = () => {
const wrapperRef = useRef(null);

View File

@ -16,7 +16,7 @@ import {
startDm,
setUserBlock,
setChatChannel,
} from '../../actions';
} from '../../store/actions';
import { escapeMd } from '../../core/utils';
const UserContextMenu = () => {

View File

@ -8,7 +8,7 @@ import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import { t } from 'ttag';
import CanvasItem from '../CanvasItem';
import { changeWindowType, selectCanvas } from '../../actions';
import { changeWindowType, selectCanvas } from '../../store/actions';
const CanvasSelect = ({ windowId }) => {

View File

@ -20,7 +20,7 @@ import {
fetchChatMessages,
showContextMenu,
setWindowTitle,
} from '../../actions';
} from '../../store/actions';
import SocketClient from '../../socket/SocketClient';

View File

@ -6,9 +6,9 @@ import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { t } from 'ttag';
import { changeWindowType } from '../../actions';
import { changeWindowType } from '../../store/actions';
import { validateEMail } from '../../utils/validation';
import { requestNewPassword } from '../../actions/fetch';
import { requestNewPassword } from '../../store/actions/fetch';
function validate(email) {
const errors = [];

View File

@ -10,9 +10,9 @@ import Captcha from '../Captcha';
import {
validateEMail, validateName, validatePassword,
} from '../../utils/validation';
import { requestRegistration } from '../../actions/fetch';
import { requestRegistration } from '../../store/actions/fetch';
import { changeWindowType, loginUser } from '../../actions';
import { changeWindowType, loginUser } from '../../store/actions';
function validate(name, email, password, confirmPassword) {

View File

@ -20,7 +20,7 @@ import {
toggleLightGrid,
toggleHistoricalView,
selectStyle,
} from '../../actions';
} from '../../store/actions';
const flexy = {

View File

@ -7,7 +7,7 @@ import React, { Suspense } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { t } from 'ttag';
import { fetchStats } from '../../actions';
import { fetchStats } from '../../store/actions';
import useInterval from '../hooks/interval';
import LogInArea from '../LogInArea';
import Tabs from '../Tabs';

View File

@ -20,7 +20,7 @@ import {
moveSouth,
moveEast,
onViewFinishChange,
} from '../actions';
} from '../store/actions';
import {
tryPlacePixel,
} from '../ui/placePixel';

View File

@ -27,7 +27,7 @@ import {
import {
onViewFinishChange,
setViewCoordinates,
} from '../actions';
} from '../store/actions';
import {
THREE_CANVAS_HEIGHT,
} from '../core/constants';

View File

@ -1,6 +1,5 @@
/*
* keypress actions
* @flow
*/
import { t } from 'ttag';
import store from '../ui/store';
@ -13,11 +12,11 @@ import {
toggleMute,
notify,
selectCanvas,
} from '../actions';
} from '../store/actions';
const usedKeys = ['g', 'h', 'x', 'm', 'r', 'p'];
function onKeyPress(event: KeyboardEvent) {
function onKeyPress(event) {
// ignore key presses if modal is open or chat is used
if (event.target.nodeName === 'INPUT'
|| event.target.nodeName === 'TEXTAREA'

3
src/store/README.md Normal file
View File

@ -0,0 +1,3 @@
# Store
We use redux as a state manager of our application:
https://redux.js.org/

View File

@ -6,7 +6,7 @@
import { t } from 'ttag';
import { dateToString } from '../core/utils';
import { dateToString } from '../../core/utils';
/*
* Adds customizeable timeout to fetch

View File

@ -1,25 +0,0 @@
/**
* Copyright 2016 Facebook, Inc.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
* use, copy, modify, and distribute this software in source code or binary
* form for use in connection with the web services and APIs provided by
* Facebook.
*
* As with any software that integrates with the Facebook platform, your use
* of this software is subject to the Facebook Developer Principles and
* Policies [http://developers.facebook.com/policy/]. This copyright notice
* shall be included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE
*/
export default () => (next) => (action) => (Array.isArray(action)
? action.map(next)
: next(action));

View File

@ -1,20 +1,18 @@
/* @flow */
import { applyMiddleware, createStore, compose } from 'redux';
import thunk from 'redux-thunk';
import { persistStore } from 'redux-persist';
import audio from './audio';
import socketClientHook from './socketClientHook';
import rendererHook from './rendererHook';
import audio from './middleware/audio';
import socketClientHook from './middleware/socketClientHook';
import rendererHook from './middleware/rendererHook';
// import ads from './ads';
import array from './array';
import promise from './promise';
import notifications from './notifications';
import title from './title';
import placePixelControl from './placePixelControl';
import extensions from './extensions';
import reducers from '../reducers';
import array from './middleware/array';
import promise from './middleware/promise';
import notifications from './middleware/notifications';
import title from './middleware/title';
import placePixelControl from './middleware/placePixelControl';
import extensions from './middleware/extensions';
import reducers from './reducers';
const store = createStore(
@ -37,9 +35,11 @@ const store = createStore(
);
export default function configureStore(onComplete: ?() => void) {
export default function configureStore(onComplete) {
persistStore(store, null, () => {
onComplete(store);
if (onComplete) {
onComplete(store);
}
});
return store;
}

View File

@ -0,0 +1,7 @@
/*
* consume array of actions
*/
export default () => (next) => (action) => (Array.isArray(action)
? action.map(next)
: next(action));

View File

@ -1,8 +1,6 @@
/* @flow
*
* play sounds using the HTML5 AudoContext
*
* */
/*
* play sounds using the HTML5 AudoContext
*/
// iPhone needs this

View File

@ -2,7 +2,6 @@
* sends events via window.pixelPlanetEvents to potential
* Extensions and Userscripts
*
* @flow
*/
import EventEmitter from 'events';

View File

@ -1,10 +1,9 @@
/*
* Hooks for placePixel
*
* @flow
*/
import { requestFromQueue } from '../ui/placePixel';
import { requestFromQueue } from '../../ui/placePixel';
export default (store) => (next) => (action) => {
switch (action.type) {

View File

@ -0,0 +1,13 @@
/*
* consume async function as action
*/
function warn(error) {
// eslint-disable-next-line no-console
console.warn(error.message || error);
throw error; // To let the caller handle the rejection
}
export default () => (next) => (action) => (typeof action.then === 'function'
? Promise.resolve(action).then(next, warn)
: next(action));

View File

@ -3,25 +3,13 @@
*
*/
/*
* set theme-color meta tag that sets the color
* of address bars on phones
*/
/*
* hooks for rendering
*/
import {
getRenderer,
initRenderer,
} from '../ui/renderer';
function setThemeColorMeta(r, g, b) {
const metaThemeColor = document.querySelector('meta[name=theme-color]');
if (metaThemeColor) {
metaThemeColor.setAttribute('content', `rgb(${r}, ${g}, ${b})`);
}
}
} from '../../ui/renderer';
export default (store) => (next) => (action) => {
const { type } = action;
@ -63,10 +51,7 @@ export default (store) => (next) => (action) => {
case 'SELECT_CANVAS':
case 'RECEIVE_ME': {
const renderer = getRenderer();
const { is3D, palette } = state.canvas;
const [r, g, b] = palette.rgb;
setThemeColorMeta(r, g, b);
const { is3D } = state.canvas;
if (is3D === renderer.is3D) {
renderer.updateCanvasData(state);

View File

@ -1,10 +1,9 @@
/*
* Hooks for websocket client to store changes
*
* @flow
*/
import SocketClient from '../socket/SocketClient';
import SocketClient from '../../socket/SocketClient';
export default (store) => (next) => (action) => {
switch (action.type) {

View File

@ -1,12 +1,21 @@
/**
*
* @flow
* set URL in adress bar, theme-color and title
*/
import {
durationToString,
} from '../core/utils';
} from '../../core/utils';
/*
* set theme-color meta tag that sets the color
* of address bars on phones
*/
function setThemeColorMeta(r, g, b) {
const metaThemeColor = document.querySelector('meta[name=theme-color]');
if (metaThemeColor) {
metaThemeColor.setAttribute('content', `rgb(${r}, ${g}, ${b})`);
}
}
const TITLE = 'PixelPlanet.fun';
@ -35,12 +44,20 @@ export default (store) => (next) => (action) => {
case 'RECEIVE_ME':
case 'RELOAD_URL':
case 'ON_VIEW_FINISH_CHANGE': {
const state = store.getState();
const {
view,
viewscale,
canvasIdent,
is3D,
} = store.getState().canvas;
} = state.canvas;
if (action.type !== 'ON_VIEW_FINISH_CHANGE') {
const [r, g, b] = state.canvas.palette.rgb;
setThemeColorMeta(r, g, b);
}
const coords = view.map((u) => Math.round(u)).join(',');
let newhash = `#${canvasIdent},${coords}`;
if (!is3D) {

View File

@ -1,31 +0,0 @@
/**
* Copyright 2016 Facebook, Inc.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
* use, copy, modify, and distribute this software in source code or binary
* form for use in connection with the web services and APIs provided by
* Facebook.
*
* As with any software that integrates with the Facebook platform, your use
* of this software is subject to the Facebook Developer Principles and
* Policies [http://developers.facebook.com/policy/]. This copyright notice
* shall be included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE
*/
function warn(error) {
// eslint-disable-next-line no-console
console.warn(error.message || error);
throw error; // To let the caller handle the rejection
}
export default () => (next) => (action) => (typeof action.then === 'function'
? Promise.resolve(action).then(next, warn)
: next(action));

View File

@ -1,10 +1,10 @@
import Palette from '../core/Palette';
import Palette from '../../core/Palette';
import {
clamp,
getIdFromObject,
getHistoricalCanvasSize,
getMaxTiledZoom,
} from '../core/utils';
} from '../../core/utils';
import {
@ -13,7 +13,7 @@ import {
DEFAULT_CANVAS_ID,
DEFAULT_CANVASES,
TILE_SIZE,
} from '../core/constants';
} from '../../core/constants';
export type CanvasState = {
canvasId: number,

View File

@ -1,4 +1,4 @@
import { MAX_CHAT_MESSAGES } from '../core/constants';
import { MAX_CHAT_MESSAGES } from '../../core/constants';
const initialState = {
/*

View File

@ -2,7 +2,7 @@
* state for open windows and modal and its content
*/
import { clamp } from '../core/utils';
import { clamp } from '../../core/utils';
const SCREEN_MARGIN_S = 30;
const SCREEN_MARGIN_EW = 70;

View File

@ -13,7 +13,7 @@ import {
receiveBigChunk,
receiveBigChunkFailure,
// preLoadedBigChunk,
} from '../actions';
} from '../store/actions';
import {
getMaxTiledZoom,
getCellInsideChunk,

View File

@ -8,7 +8,7 @@ import {
requestBigChunk,
receiveBigChunk,
receiveBigChunkFailure,
} from '../actions';
} from '../store/actions';
import {
getChunkOfPixel,
getOffsetOfPixel,

View File

@ -19,7 +19,7 @@ import {
import {
setHover,
selectColor,
} from '../actions';
} from '../store/actions';
import { tryPlacePixel } from './placePixel';

View File

@ -16,7 +16,7 @@ import {
placedPixels,
pixelWait,
updatePixel,
} from '../actions';
} from '../store/actions';
import SocketClient from '../socket/SocketClient';
let pixelTimeout = null;

View File

@ -9,7 +9,7 @@
import { t } from 'ttag';
import Renderer2D from './Renderer2D';
import { sweetAlert } from '../actions';
import { sweetAlert } from '../store/actions';
import { isWebGL2Available } from '../core/utils';
const dummyRenderer = {