src/persistState.js
import getStore from './initRedux.js';
const checkState = (state) => {
return (state && state.rotorsData && state.rotorsData.xy);
};
/**
* load last State
* @return {object} saved state
*/
export const loadState = () => {
const url = window.location.search;
let result = 0;
if (url.length > 10) {
try {
const url = window.location.search;
result = decodeURL(url);
} catch (e) {
//redirect to 404
}
}
else {
try {
const serializedState = localStorage.getItem("state");
if (serializedState === null) {
result = undefined;
}
result = JSON.parse(serializedState);
} catch (err) {
result = undefined;
}
}
return checkState(result) ? result : undefined;
};
/**
* short name for some key in json
*/
const keyList=[
{key:"rotorsData",zip:"R"},
{key:"width",zip:"W"},
{key:"step",zip:"S"},
{key:"start",zip:"C"},
{key:"isPlaying",zip:"P"},
{key:"options",zip:"O"},
{key:"hasHSL",zip:"H"},
{key:"showAxes",zip:"A"},
{key:"progressedSteps",zip:"I"},
{key:"steps",zip:"J"},
{key:"showMoreControl",zip:"G"},
{key:"xy",zip:"D1"},
{key:"yz",zip:"D2"},
{key:"xz",zip:"D3"},
];
/**
* some other character replacement which are not ok in url
*/
const replaceList=[
{from:'true',to:'T'},
{from:'false',to:'F'},
{from:'{',to:'Q'},
{from:'}',to:'X'},
{from:'[',to:'E'},
{from:']',to:'Z'},
{from:',',to:'V'},
];
/**
* shortening url
*/
const encodeURL = (state) => {
let zipUrl=JSON.stringify(sanitizeState(state));
for(var i=0;i<keyList.length;i++) {
zipUrl=zipUrl.replace(new RegExp('"'+keyList[i].key+'":',"g"),keyList[i].zip);
}
for(var j=0; j<replaceList.length; j++) {
var from=replaceList[j].from;
if(from.length<2)from="\\"+from;
zipUrl=zipUrl.replace(new RegExp(from,"g"),replaceList[j].to);
}
zipUrl="?" + encodeURIComponent(zipUrl);
return zipUrl;
};
const isArray = (data) => {
return (Object.prototype.toString.call(data) === "[object Array]");
};
const sanitizeState = (state) => {
if (isArray(state)) {
for (let sti of state) {
sanitizeState(sti);
}
}
else if(typeof(state)=='object') {
for (let [k, v] of Object.entries(state)) {
if (keyList.filter(x => x.key == k).length < 1) {
delete state[k];
}
sanitizeState(state[k]);
}
}
return state;
};
/**
* decode url
*/
const decodeURL = (url) => {
let decodedUrl = decodeURIComponent(url.slice(1));
for (let item of replaceList) {
decodedUrl = decodedUrl.replace(new RegExp(item.to, "g"), item.from);
}
for (let item of keyList) {
decodedUrl = decodedUrl.replace(new RegExp(item.zip, "g"), '"' + item.key + '":');
}
let state = JSON.parse(decodedUrl);
return sanitizeState(state);
};
/**
* change browser url to new state and reload it
*/
export const setUrlByState = () => {
const state = getStore().getState();
window.location.search = encodeURL(state);
};
export const getUrlByState = () => {
const state = getStore().getState();
return window.location.href+encodeURL(state);
};
/**
* save last State
*/
export const saveState = (state) => {
try {
localStorage.setItem("state", JSON.stringify(state));
}
catch (err) {
}
};