2018-08-01 18:09:58 +00:00
|
|
|
import {combineReducers} from 'redux';
|
2018-10-04 13:19:14 +00:00
|
|
|
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
|
2018-10-04 12:48:09 +00:00
|
|
|
FETCH_CREDENTIALS, INIT_ETHER_CONVERSIONS, UPDATE_ETHER_CONVERSIONS} from "../actions";
|
2018-08-07 14:09:55 +00:00
|
|
|
|
|
|
|
const BN_FACTOR = 10000;
|
2018-10-03 11:51:14 +00:00
|
|
|
const VOID_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
|
|
const DEFAULT_HOST = 'localhost:8000';
|
2018-10-04 14:25:35 +00:00
|
|
|
const MAX_ELEMENTS = 200;
|
2018-08-07 14:09:55 +00:00
|
|
|
|
|
|
|
const entitiesDefaultState = {
|
|
|
|
accounts: [],
|
|
|
|
blocks: [],
|
|
|
|
transactions: [],
|
|
|
|
processes: [],
|
|
|
|
processLogs: [],
|
|
|
|
contracts: [],
|
|
|
|
contractProfiles: [],
|
2018-08-16 11:17:13 +00:00
|
|
|
contractFunctions: [],
|
2018-08-16 15:18:07 +00:00
|
|
|
contractDeploys: [],
|
2018-08-30 12:13:37 +00:00
|
|
|
contractCompiles: [],
|
2018-08-09 19:33:07 +00:00
|
|
|
contractLogs: [],
|
2018-08-08 19:03:46 +00:00
|
|
|
commands: [],
|
|
|
|
messages: [],
|
2018-08-08 19:09:40 +00:00
|
|
|
messageChannels: [],
|
2018-08-10 10:31:10 +00:00
|
|
|
versions: [],
|
2018-08-13 11:08:59 +00:00
|
|
|
plugins: [],
|
2018-08-30 12:13:37 +00:00
|
|
|
ensRecords: [],
|
2018-08-31 20:44:43 +00:00
|
|
|
files: [],
|
2018-08-30 12:13:37 +00:00
|
|
|
gasOracleStats: [],
|
|
|
|
currentFiles: []
|
2018-08-07 14:09:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const sorter = {
|
|
|
|
blocks: function(a, b) {
|
|
|
|
return b.number - a.number;
|
|
|
|
},
|
|
|
|
transactions: function(a, b) {
|
|
|
|
return ((BN_FACTOR * b.blockNumber) + b.transactionIndex) - ((BN_FACTOR * a.blockNumber) + a.transactionIndex);
|
|
|
|
},
|
|
|
|
processLogs: function(a, b) {
|
|
|
|
return a.timestamp - b.timestamp;
|
2018-08-08 19:03:46 +00:00
|
|
|
},
|
2018-08-09 19:33:07 +00:00
|
|
|
contractLogs: function(a, b) {
|
|
|
|
return a.timestamp - b.timestamp;
|
|
|
|
},
|
2018-08-08 19:03:46 +00:00
|
|
|
messages: function(a, b) {
|
|
|
|
return a.time - b.time;
|
2018-08-31 09:57:52 +00:00
|
|
|
},
|
|
|
|
commands: function(a, b) {
|
|
|
|
return b.timestamp - a.timestamp;
|
2018-08-30 12:13:37 +00:00
|
|
|
},
|
|
|
|
files: function(a, b) {
|
|
|
|
if (a.name < b.name) return -1;
|
|
|
|
if (a.name > b.name) return 1;
|
|
|
|
return 0;
|
2018-08-07 14:09:55 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const filtrer = {
|
|
|
|
processes: function(process, index, self) {
|
|
|
|
return index === self.findIndex((t) => t.name === process.name);
|
|
|
|
},
|
|
|
|
contracts: function(contract, index, self) {
|
2018-08-10 16:57:37 +00:00
|
|
|
return index === self.findIndex((t) => t.className === contract.className);
|
2018-08-07 14:09:55 +00:00
|
|
|
},
|
|
|
|
accounts: function(account, index, self) {
|
|
|
|
return index === self.findIndex((t) => t.address === account.address);
|
|
|
|
},
|
|
|
|
blocks: function(block, index, self) {
|
2018-10-04 14:25:35 +00:00
|
|
|
if (index > MAX_ELEMENTS) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-07 14:09:55 +00:00
|
|
|
return index === self.findIndex((t) => t.number === block.number);
|
|
|
|
},
|
|
|
|
transactions: function(tx, index, self) {
|
2018-10-04 14:25:35 +00:00
|
|
|
if (index > MAX_ELEMENTS) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-07 14:09:55 +00:00
|
|
|
return index === self.findIndex((t) => (
|
|
|
|
t.blockNumber === tx.blockNumber && t.transactionIndex === tx.transactionIndex
|
|
|
|
));
|
2018-08-14 09:23:48 +00:00
|
|
|
},
|
|
|
|
ensRecords: function(record, index, self) {
|
2018-10-03 11:51:14 +00:00
|
|
|
return record.name && record.address && record.address !== VOID_ADDRESS && index === self.findIndex((r) => (
|
2018-09-07 14:40:28 +00:00
|
|
|
r.address === record.address && r.name === record.name
|
2018-08-14 09:23:48 +00:00
|
|
|
));
|
2018-08-30 12:13:37 +00:00
|
|
|
},
|
|
|
|
files: function(file, index, self) {
|
|
|
|
return index === self.findIndex((f) => (
|
|
|
|
file.name === f.name
|
|
|
|
));
|
2018-08-31 20:47:58 +00:00
|
|
|
},
|
|
|
|
gasOracleStats: function(stat, index, _self) {
|
|
|
|
return index === 0; // Only keep last one
|
2018-09-19 14:59:01 +00:00
|
|
|
},
|
|
|
|
versions: function(version, index, self) {
|
|
|
|
return index === self.findIndex((v) => v.value === version.value && v.name === version.name);
|
2018-08-07 14:09:55 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function entities(state = entitiesDefaultState, action) {
|
2018-08-30 12:13:37 +00:00
|
|
|
if (action.type === FILES[SUCCESS]) {
|
|
|
|
return {...state, files: action.files};
|
|
|
|
}
|
2018-08-07 14:09:55 +00:00
|
|
|
for (let name of Object.keys(state)) {
|
|
|
|
let filter = filtrer[name] || (() => true);
|
|
|
|
let sort = sorter[name] || (() => true);
|
2018-08-10 10:31:10 +00:00
|
|
|
if (action[name] && action[name].length > 1) {
|
2018-08-07 14:09:55 +00:00
|
|
|
return {...state, [name]: [...action[name], ...state[name]].filter(filter).sort(sort)};
|
|
|
|
}
|
|
|
|
if (action[name] && action[name].length === 1) {
|
|
|
|
let entity = action[name][0];
|
|
|
|
let nested = Object.keys(state).reduce((acc, entityName) => {
|
|
|
|
if (entity[entityName] && entity[entityName].length > 0) {
|
|
|
|
let entityFilter = filtrer[entityName] || (() => true);
|
|
|
|
let entitySort = sorter[entityName] || (() => true);
|
|
|
|
acc[entityName] = [...entity[entityName], ...state[entityName]].filter(entityFilter).sort(entitySort);
|
|
|
|
}
|
|
|
|
return acc;
|
|
|
|
}, {});
|
|
|
|
return {
|
|
|
|
...state, ...nested, [name]: [...action[name], ...state[name]].filter(filter).sort(sort)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2018-09-19 14:59:01 +00:00
|
|
|
function errorMessage(_state = null, action) {
|
|
|
|
return action.error || null;
|
2018-08-07 14:09:55 +00:00
|
|
|
}
|
|
|
|
|
2018-08-14 16:17:47 +00:00
|
|
|
function errorEntities(state = {}, action) {
|
|
|
|
if (!action.type.endsWith(SUCCESS)) {
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
let newState = {};
|
|
|
|
for (let name of Object.keys(entitiesDefaultState)) {
|
|
|
|
if (action[name] && action[name].length > 0) {
|
|
|
|
newState[name] = action[name][0].error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {...state, ...newState};
|
|
|
|
}
|
|
|
|
|
2018-08-07 14:09:55 +00:00
|
|
|
function loading(_state = false, action) {
|
2018-09-04 17:51:33 +00:00
|
|
|
return action.type.endsWith(REQUEST) && !action.noLoading;
|
2018-08-07 14:09:55 +00:00
|
|
|
}
|
2018-08-01 13:13:51 +00:00
|
|
|
|
2018-08-30 12:13:37 +00:00
|
|
|
function compilingContract(state = false, action) {
|
2018-09-07 14:40:28 +00:00
|
|
|
if (action.type === CONTRACT_COMPILE[REQUEST]) {
|
2018-08-30 12:13:37 +00:00
|
|
|
return true;
|
|
|
|
} else if (action.type === CONTRACT_COMPILE[FAILURE] || action.type === CONTRACT_COMPILE[SUCCESS]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2018-10-03 11:51:14 +00:00
|
|
|
const DEFAULT_CREDENTIALS_STATE = {host: DEFAULT_HOST, token: '', authenticated: false};
|
|
|
|
|
|
|
|
function credentials(state = DEFAULT_CREDENTIALS_STATE, action) {
|
2018-09-19 14:59:01 +00:00
|
|
|
if (action.type === LOGOUT[SUCCESS]) {
|
2018-10-03 11:51:14 +00:00
|
|
|
return DEFAULT_CREDENTIALS_STATE;
|
2018-09-19 14:59:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (action.type === AUTHENTICATE[FAILURE]) {
|
2018-10-03 11:51:14 +00:00
|
|
|
return {error: action.error, authenticated: false};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (action.type === AUTHENTICATE[SUCCESS]) {
|
|
|
|
return {...state, ...{authenticated: true, token: action.token, host: action.host, error: null}};
|
2018-09-19 14:59:01 +00:00
|
|
|
}
|
|
|
|
|
2018-10-03 11:51:14 +00:00
|
|
|
if (action.type === FETCH_CREDENTIALS[SUCCESS]) {
|
|
|
|
return {...state, ...{token: action.token, host: action.host}};
|
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
2018-09-07 14:40:28 +00:00
|
|
|
}
|
|
|
|
|
2018-10-04 12:48:09 +00:00
|
|
|
function etherConversions(state = [], action) {
|
|
|
|
if ([INIT_ETHER_CONVERSIONS, UPDATE_ETHER_CONVERSIONS].includes(action.type)) {
|
|
|
|
return action.payload;
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2018-10-04 13:19:14 +00:00
|
|
|
const DEFAULT_TABS = [
|
|
|
|
{value: "Contracts", to: "/embark/contracts", icon: "box", base: '/embark/contracts'},
|
|
|
|
{value: "Explorer", to: "/embark/explorer/accounts", icon: "activity", base: '/embark/explorer'},
|
|
|
|
{value: "Fiddle", to: "/embark/fiddle", icon: "codepen", base: '/embark/fiddle'},
|
|
|
|
{value: "Documentation", to: "/embark/documentation", icon: "file-text", base: '/embark/documentation'},
|
|
|
|
{value: "Utils", to: "/embark/utilities/converter", icon: "settings", base: '/embark/utilities'}
|
|
|
|
];
|
|
|
|
|
|
|
|
function tabs(state = DEFAULT_TABS, action) {
|
|
|
|
if (action.type === '@@router/LOCATION_CHANGE'){
|
|
|
|
const newState = [...state];
|
|
|
|
const activeTab = newState.find(tab => action.payload.location.pathname.startsWith(tab.base));
|
|
|
|
if (activeTab) {
|
|
|
|
activeTab.to = action.payload.location.pathname;
|
|
|
|
return newState;
|
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2018-08-02 10:27:33 +00:00
|
|
|
const rootReducer = combineReducers({
|
2018-08-07 14:09:55 +00:00
|
|
|
entities,
|
|
|
|
loading,
|
2018-08-30 12:13:37 +00:00
|
|
|
compilingContract,
|
2018-08-14 16:17:47 +00:00
|
|
|
errorMessage,
|
2018-09-07 14:40:28 +00:00
|
|
|
errorEntities,
|
2018-10-04 12:48:09 +00:00
|
|
|
credentials,
|
2018-10-04 13:19:14 +00:00
|
|
|
etherConversions,
|
|
|
|
tabs
|
2018-08-02 10:27:33 +00:00
|
|
|
});
|
2018-08-01 13:13:51 +00:00
|
|
|
|
|
|
|
export default rootReducer;
|