store / reducers fixes, move websocketClient to reducers
This commit is contained in:
parent
337fbf2462
commit
e7a16fa3b9
|
@ -1,8 +1,5 @@
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
import swal from 'sweetalert2';
|
|
||||||
import 'sweetalert2/src/sweetalert2.scss';
|
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
Action,
|
Action,
|
||||||
ThunkAction,
|
ThunkAction,
|
||||||
|
@ -11,13 +8,27 @@ import type {
|
||||||
import type { Cell } from '../core/Cell';
|
import type { Cell } from '../core/Cell';
|
||||||
import type { ColorIndex } from '../core/Palette';
|
import type { ColorIndex } from '../core/Palette';
|
||||||
|
|
||||||
import ProtocolClient from '../socket/ProtocolClient';
|
|
||||||
import { loadImage } from '../ui/loadImage';
|
import { loadImage } from '../ui/loadImage';
|
||||||
import {
|
import {
|
||||||
getColorIndexOfPixel,
|
getColorIndexOfPixel,
|
||||||
} from '../core/utils';
|
} from '../core/utils';
|
||||||
|
|
||||||
|
|
||||||
|
export function sweetAlert(
|
||||||
|
title: string,
|
||||||
|
text: string,
|
||||||
|
icon: string,
|
||||||
|
confirmButtonText: string,
|
||||||
|
): Action {
|
||||||
|
return {
|
||||||
|
type: 'ALERT',
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
icon,
|
||||||
|
confirmButtonText,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function toggleChatBox(): Action {
|
export function toggleChatBox(): Action {
|
||||||
return {
|
return {
|
||||||
type: 'TOGGLE_CHAT_BOX',
|
type: 'TOGGLE_CHAT_BOX',
|
||||||
|
@ -255,12 +266,12 @@ export function requestPlacePixel(
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(pixelFailure());
|
dispatch(pixelFailure());
|
||||||
swal.fire({
|
dispatch(sweetAlert(
|
||||||
title: (errorTitle || `Error ${response.status}`),
|
(errorTitle || `Error ${response.status}`),
|
||||||
text: errors[0].msg,
|
errors[0].msg,
|
||||||
icon: 'error',
|
'error',
|
||||||
confirmButtonText: 'OK',
|
'OK',
|
||||||
});
|
));
|
||||||
} finally {
|
} finally {
|
||||||
dispatch(setPlaceAllowed(true));
|
dispatch(setPlaceAllowed(true));
|
||||||
}
|
}
|
||||||
|
@ -418,7 +429,6 @@ export function fetchChunk(canvasId, center: Cell): PromiseAction {
|
||||||
return async (dispatch) => {
|
return async (dispatch) => {
|
||||||
dispatch(requestBigChunk(center));
|
dispatch(requestBigChunk(center));
|
||||||
try {
|
try {
|
||||||
ProtocolClient.registerChunk([cx, cy]);
|
|
||||||
const url = `/chunks/${canvasId}/${cx}/${cy}.bmp`;
|
const url = `/chunks/${canvasId}/${cx}/${cy}.bmp`;
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
|
@ -475,7 +485,6 @@ export function receiveMe(
|
||||||
minecraftname,
|
minecraftname,
|
||||||
canvases,
|
canvases,
|
||||||
} = me;
|
} = me;
|
||||||
ProtocolClient.setName(name);
|
|
||||||
return {
|
return {
|
||||||
type: 'RECEIVE_ME',
|
type: 'RECEIVE_ME',
|
||||||
name: (name) || null,
|
name: (name) || null,
|
||||||
|
@ -504,7 +513,6 @@ export function receiveStats(
|
||||||
export function setName(
|
export function setName(
|
||||||
name: string,
|
name: string,
|
||||||
): Action {
|
): Action {
|
||||||
ProtocolClient.setName(name);
|
|
||||||
return {
|
return {
|
||||||
type: 'SET_NAME',
|
type: 'SET_NAME',
|
||||||
name,
|
name,
|
||||||
|
@ -557,9 +565,7 @@ export function fetchMe(): PromiseAction {
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const me = await response.json();
|
const me = await response.json();
|
||||||
await dispatch(receiveMe(me));
|
dispatch(receiveMe(me));
|
||||||
const state = getState();
|
|
||||||
ProtocolClient.setCanvas(state.canvas.canvasId);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -660,18 +666,14 @@ export function onViewFinishChange(): Action {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function urlChange(): PromiseAction {
|
export function urlChange(): PromiseAction {
|
||||||
return async (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
await dispatch(reloadUrl());
|
dispatch(reloadUrl());
|
||||||
const state = getState();
|
|
||||||
ProtocolClient.setCanvas(state.canvas.canvasId);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function switchCanvas(canvasId: number): PromiseAction {
|
export function switchCanvas(canvasId: number): PromiseAction {
|
||||||
return async (dispatch, getState) => {
|
return async (dispatch, getState) => {
|
||||||
await dispatch(selectCanvas(canvasId));
|
await dispatch(selectCanvas(canvasId));
|
||||||
const state = getState();
|
|
||||||
ProtocolClient.setCanvas(state.canvas.canvasId);
|
|
||||||
dispatch(onViewFinishChange());
|
dispatch(onViewFinishChange());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,12 @@ import type { State } from '../reducers';
|
||||||
export type Action =
|
export type Action =
|
||||||
{ type: 'LOGGED_OUT' }
|
{ type: 'LOGGED_OUT' }
|
||||||
// my actions
|
// my actions
|
||||||
|
| { type: 'ALERT',
|
||||||
|
title: string,
|
||||||
|
text: string,
|
||||||
|
icon: string,
|
||||||
|
confirmButtonText: string,
|
||||||
|
}
|
||||||
| { type: 'TOGGLE_GRID' }
|
| { type: 'TOGGLE_GRID' }
|
||||||
| { type: 'TOGGLE_PIXEL_NOTIFY' }
|
| { type: 'TOGGLE_PIXEL_NOTIFY' }
|
||||||
| { type: 'TOGGLE_AUTO_ZOOM_IN' }
|
| { type: 'TOGGLE_AUTO_ZOOM_IN' }
|
||||||
|
@ -38,13 +44,27 @@ export type Action =
|
||||||
| { type: 'RECEIVE_IMAGE_TILE', center: Cell, tile: Image }
|
| { type: 'RECEIVE_IMAGE_TILE', center: Cell, tile: Image }
|
||||||
| { type: 'RECEIVE_BIG_CHUNK_FAILURE', center: Cell, error: Error }
|
| { type: 'RECEIVE_BIG_CHUNK_FAILURE', center: Cell, error: Error }
|
||||||
| { type: 'RECEIVE_COOLDOWN', waitSeconds: number }
|
| { type: 'RECEIVE_COOLDOWN', waitSeconds: number }
|
||||||
| { type: 'RECEIVE_PIXEL_UPDATE', i: number, j: number, offset: number, color: ColorIndex }
|
| { type: 'RECEIVE_PIXEL_UPDATE',
|
||||||
|
i: number,
|
||||||
|
j: number,
|
||||||
|
offset: number,
|
||||||
|
color: ColorIndex,
|
||||||
|
}
|
||||||
| { type: 'RECEIVE_ONLINE', online: number }
|
| { type: 'RECEIVE_ONLINE', online: number }
|
||||||
| { type: 'RECEIVE_CHAT_MESSAGE', name: string, text: string }
|
| { type: 'RECEIVE_CHAT_MESSAGE', name: string, text: string }
|
||||||
| { type: 'RECEIVE_CHAT_HISTORY', data: Array }
|
| { type: 'RECEIVE_CHAT_HISTORY', data: Array }
|
||||||
| { type: 'RECEIVE_ME', name: string, waitSeconds: number, messages: Array,
|
| { type: 'RECEIVE_ME',
|
||||||
mailreg: boolean, totalPixels: number, dailyTotalPixels: number,
|
name: string,
|
||||||
ranking: number, dailyRanking: number, minecraftname: string, canvases: Object}
|
waitSeconds: number,
|
||||||
|
messages: Array,
|
||||||
|
mailreg: boolean,
|
||||||
|
totalPixels: number,
|
||||||
|
dailyTotalPixels: number,
|
||||||
|
ranking: number,
|
||||||
|
dailyRanking: number,
|
||||||
|
minecraftname: string,
|
||||||
|
canvases: Object
|
||||||
|
}
|
||||||
| { type: 'RECEIVE_STATS', totalRanking: Object, totalDailyRanking: Object }
|
| { type: 'RECEIVE_STATS', totalRanking: Object, totalDailyRanking: Object }
|
||||||
| { type: 'SET_NAME', name: string }
|
| { type: 'SET_NAME', name: string }
|
||||||
| { type: 'SET_MINECRAFT_NAME', minecraftname: string }
|
| { type: 'SET_MINECRAFT_NAME', minecraftname: string }
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import type { State } from '../reducers';
|
|
||||||
import store from '../ui/store';
|
import store from '../ui/store';
|
||||||
import { requestPlacePixel } from '../actions';
|
import { requestPlacePixel } from '../actions';
|
||||||
|
|
||||||
|
@ -18,7 +17,7 @@ function onCaptcha(token: string) {
|
||||||
const { canvasId, coordinates, color } = window.pixel;
|
const { canvasId, coordinates, color } = window.pixel;
|
||||||
|
|
||||||
store.dispatch(requestPlacePixel(canvasId, coordinates, color, token));
|
store.dispatch(requestPlacePixel(canvasId, coordinates, color, token));
|
||||||
grecaptcha.reset();
|
window.grecaptcha.reset();
|
||||||
}
|
}
|
||||||
// https://stackoverflow.com/questions/41717304/recaptcha-google-data-callback-with-angularjs
|
// https://stackoverflow.com/questions/41717304/recaptcha-google-data-callback-with-angularjs
|
||||||
window.onCaptcha = onCaptcha;
|
window.onCaptcha = onCaptcha;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
import { playAd } from '../ui/ads';
|
import { playAd } from '../ui/ads';
|
||||||
|
|
||||||
|
|
||||||
export default (store) => (next) => (action) => {
|
export default () => (next) => (action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'PLACE_PIXEL': {
|
case 'PLACE_PIXEL': {
|
||||||
// wait 1 second
|
// wait 1 second
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
import track from './track';
|
import track from './track';
|
||||||
|
|
||||||
export default (store) => (next) => (action) => {
|
export default () => (next) => (action) => {
|
||||||
track(action);
|
track(action);
|
||||||
return next(action);
|
return next(action);
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,6 +20,6 @@
|
||||||
* DEALINGS IN THE SOFTWARE
|
* DEALINGS IN THE SOFTWARE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default (store) => (next) => (action) => (Array.isArray(action)
|
export default () => (next) => (action) => (Array.isArray(action)
|
||||||
? action.map(next)
|
? action.map(next)
|
||||||
: next(action));
|
: next(action));
|
||||||
|
|
|
@ -3,11 +3,13 @@
|
||||||
import { applyMiddleware, createStore, compose } from 'redux';
|
import { applyMiddleware, createStore, compose } from 'redux';
|
||||||
import thunk from 'redux-thunk';
|
import thunk from 'redux-thunk';
|
||||||
import { createLogger } from 'redux-logger';
|
import { createLogger } from 'redux-logger';
|
||||||
import { persistStore, autoRehydrate } from 'redux-persist';
|
import { persistStore } from 'redux-persist';
|
||||||
|
|
||||||
import ads from './ads';
|
|
||||||
import audio from './audio';
|
import audio from './audio';
|
||||||
import analytics from './analytics';
|
import swal from './sweetAlert';
|
||||||
|
import protocolClientHook from './protocolClientHook';
|
||||||
|
// import ads from './ads';
|
||||||
|
// import analytics from './analytics';
|
||||||
import array from './array';
|
import array from './array';
|
||||||
import promise from './promise';
|
import promise from './promise';
|
||||||
import notifications from './notifications';
|
import notifications from './notifications';
|
||||||
|
@ -18,7 +20,7 @@ import reducers from '../reducers';
|
||||||
const isDebuggingInChrome = __DEV__ && !!window.navigator.userAgent;
|
const isDebuggingInChrome = __DEV__ && !!window.navigator.userAgent;
|
||||||
|
|
||||||
const logger = createLogger({
|
const logger = createLogger({
|
||||||
predicate: (getState, action) => isDebuggingInChrome,
|
predicate: () => isDebuggingInChrome,
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
duration: true,
|
duration: true,
|
||||||
});
|
});
|
||||||
|
@ -31,11 +33,13 @@ const store = createStore(
|
||||||
thunk,
|
thunk,
|
||||||
promise,
|
promise,
|
||||||
array,
|
array,
|
||||||
ads,
|
swal,
|
||||||
audio,
|
audio,
|
||||||
notifications,
|
notifications,
|
||||||
title,
|
title,
|
||||||
analytics,
|
protocolClientHook,
|
||||||
|
// ads,
|
||||||
|
// analytics,
|
||||||
logger,
|
logger,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
export default (store) => (next) => (action) => {
|
export default () => (next) => (action) => {
|
||||||
try {
|
try {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'PLACE_PIXEL': {
|
case 'PLACE_PIXEL': {
|
||||||
|
|
|
@ -25,6 +25,6 @@ function warn(error) {
|
||||||
throw error; // To let the caller handle the rejection
|
throw error; // To let the caller handle the rejection
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (store) => (next) => (action) => (typeof action.then === 'function'
|
export default () => (next) => (action) => (typeof action.then === 'function'
|
||||||
? Promise.resolve(action).then(next, warn)
|
? Promise.resolve(action).then(next, warn)
|
||||||
: next(action));
|
: next(action));
|
||||||
|
|
51
src/store/protocolClientHook.js
Normal file
51
src/store/protocolClientHook.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Hooks for websocket client to store changes
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
|
||||||
|
import ProtocolClient from '../socket/ProtocolClient';
|
||||||
|
|
||||||
|
export default (store) => (next) => (action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case 'RECEIVE_BIG_CHUNK': {
|
||||||
|
const [, cx, cy] = action.center;
|
||||||
|
ProtocolClient.registerChunk([cx, cy]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'RECEIVE_ME': {
|
||||||
|
const { name } = action;
|
||||||
|
ProtocolClient.setName(name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'SET_NAME': {
|
||||||
|
const { name } = action;
|
||||||
|
ProtocolClient.setName(name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
const ret = next(action);
|
||||||
|
|
||||||
|
// executed after reducers
|
||||||
|
switch (action.type) {
|
||||||
|
case 'RELOAD_URL':
|
||||||
|
case 'SELECT_CANVAS':
|
||||||
|
case 'RECEIVE_ME': {
|
||||||
|
const state = store.getState();
|
||||||
|
const { canvasId } = state.canvas;
|
||||||
|
ProtocolClient.setCanvas(canvasId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
31
src/store/sweetAlert.js
Normal file
31
src/store/sweetAlert.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
|
||||||
|
import swal from 'sweetalert2';
|
||||||
|
import 'sweetalert2/src/sweetalert2.scss';
|
||||||
|
|
||||||
|
export default () => (next) => (action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case 'ALERT': {
|
||||||
|
const {
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
icon,
|
||||||
|
confirmButtonText,
|
||||||
|
} = action;
|
||||||
|
swal.fire({
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
icon,
|
||||||
|
confirmButtonText,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
return next(action);
|
||||||
|
};
|
|
@ -26,12 +26,12 @@ import type { Action } from '../actions/types';
|
||||||
|
|
||||||
|
|
||||||
export default function track(action: Action): void {
|
export default function track(action: Action): void {
|
||||||
if (typeof ga === 'undefined') return;
|
if (typeof window.ga === 'undefined') return;
|
||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'PLACE_PIXEL': {
|
case 'PLACE_PIXEL': {
|
||||||
const [x, y] = action.coordinates;
|
const [x, y] = action.coordinates;
|
||||||
ga('send', {
|
window.ga('send', {
|
||||||
hitType: 'event',
|
hitType: 'event',
|
||||||
eventCategory: 'Place',
|
eventCategory: 'Place',
|
||||||
eventAction: action.color,
|
eventAction: action.color,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user