UNPKG

tronair-gui

Version:

Web application/GUI for performing airdrops on the TRON blockchain

839 lines (770 loc) 30.2 kB
import React, { Component } from 'react'; import LocalizedStrings from 'react-localization'; import './App.css'; import TronWeb from 'tronweb'; import SubmitScreen from './SubmitScreen.js'; import ReviewScreen from './ReviewScreen.js'; import SettingsScreen from './SettingsScreen.js'; import StartScreen from './StartScreen.js'; import DataSheet_localizationSheet from './DataSheet_localizationSheet.js'; import DataSheet_acc_tokens from './DataSheet_acc_tokens.js'; import DataSheet_token_list from './DataSheet_token_list.js'; import DataSheet_recipients from './DataSheet_recipients.js'; import DataSheet_SR_list from './DataSheet_SR_list.js'; import Swal from 'sweetalert2'; const crit = require("tronair-cli/criterias.js"); const addr_list = [ 'TMVHPh6KAcj7NxxxRh6qqbh9jimzVvoDKT', 'TB1vS3FETs7eREwfEf3mRo6vSpbRWBWAzZ', 'TGNguKRZQJ7xon3SUfyiV4nmd6WL2ssEwQ', 'TKGkFLBExpc3XT4JfzfvBvPwCYr4MHSqm4', 'TFN69PhBf27fZEnVHVr8im9AC1BxvLrUzE', 'TX4P5tftdKCswhdq4Ynm22QkTaF4vWDQhj', 'TYMB196VRk66mZFN5RR1KYDqH9ZgQznBN7', 'TDGy2M9qWBepSHDEutWWxWd1JZfmAed3BP', 'TVcSkgpis7NBdmXfxjtueFC1ZwkSa5WEYH', 'TDFMdF614b9YgYYja28yz9v2z2BKNtPXZm', 'TXbNbg3SrsbsoZbn6raZfujEDuhJPVbaG5', 'TKP4bdHND2R7xnQC6tUbSnMem6iW4JEUD4', 'TNtPJVFFGWYRYXUaa1XJhW6MCoNQzW1nkk' ]; export default class App extends Component { constructor(props) { super(props); this.dataSheets = {}; this.dataSheets['localizationSheet'] = new DataSheet_localizationSheet('localizationSheet', this.dataSheetDidUpdate); this.dataSheets['acc_tokens'] = new DataSheet_acc_tokens('acc_tokens', this.dataSheetDidUpdate); this.dataSheets['token_list'] = new DataSheet_token_list('token_list', this.dataSheetDidUpdate); this.dataSheets['recipients'] = new DataSheet_recipients('recipients', this.dataSheetDidUpdate); this.dataSheets['SR_list'] = new DataSheet_SR_list('SR_list', this.dataSheetDidUpdate); this.dataSlots = {}; this.dataSlots['ds_total_transfers'] = 0; this.dataSlots['ds_transfer_count'] = 0; this.dataSlots['ds_status_ok'] = false; this.dataSlots['ds_help_address'] = 'TWqKTJ5JhyD7rsbbWzEvS5ZZD9Q5QPPvSH'; this.dataSlots['ds_approved_addr_list'] = addr_list; this.dataSlots['ds_activeLang'] = "en"; this.dataSlots['ds_userAcceptedContract'] = "0"; this.dataSlots['ds_isLoggedIn'] = "0"; this.dataSlots['ds_drop_token'] = ""; this.dataSlots['ds_drop_token_def'] = null; this.dataSlots['ds_login_method'] = ""; this.dataSlots['ds_acc_addr'] = ""; this.dataSlots['ds_acc_pk'] = ""; this.dataSlots['ds_acc_tokens'] = []; this.dataSlots['ds_login_state'] = "0"; this.dataSlots['ds_drop_type'] = {value: 0, label: 'Total Drop Amount', type: 'total'}; this.dataSlots['ds_drop_to_holders'] = "false"; this.dataSlots['ds_drop_to_voters'] = "false"; this.dataSlots['ds_and_or_def'] = {value: 0,label: 'and'}; this.dataSlots['ds_token_hold_addr_def'] = null; this.dataSlots['ds_sr_vote_addr_def'] = null; this.dataSlots['ds_and_or'] = "and"; this.dataSlots['ds_token_hold_addr'] = ""; this.dataSlots['ds_sr_vote_addr'] = ""; this.dataSlots['ds_is_weighted'] = "true"; this.dataSlots['ds_can_weight'] = false; this.dataSlots['ds_can_review'] = "false"; this.dataSlots['ds_step1'] = ""; this.dataSlots['ds_step2'] = ""; this.dataSlots['ds_step3'] = ""; this.dataSlots['ds_has_tronlink'] = "false"; this.dataSlots['ds_drop_amount'] = ""; this.dataSlots['ds_summary_confirm'] = ""; this.dataSlots['ds_save_dir'] = "~/Desktop"; this.dataSlots['ds_save_data'] = ""; this.dataSlots['ds_tl_state'] = "1"; this.dataSlots['ds_commence_drop'] = "0"; this.dataSlots['ds_bw_total'] = 0; this.dataSlots['ds_help_total'] = 0; this.dataSlots['ds_trx_total'] = 0; this.dataSlots['ds_bw_pct'] = 0; this.dataSlots['ds_help_pct'] = 0; this.dataSlots['ds_hold_num'] = 0; this.dataSlots['ds_vote_num'] = 0; this.dataSlots['ds_drop_num'] = 0; this.dataSlots['ds_drop_lim'] = 0; this.dataSlots['ds_max_amount'] = 0; this.dataSlots['ds_win_width'] = 1000; this.dataSlots['ds_airdrop_array'] = []; this.dataSlots['ds_success_list'] = []; this.dataSlots['ds_failure_list'] = []; this.dataSlots['ds_voter_list'] = []; this.dataSlots['ds_holder_list'] = []; this.dataSlots['ds_drop_start'] = false; this.dataSlots['ds_airdrop_trx'] = 0; this.dataSlots['ds_airdrop_token'] = 0; this.dataSlots['ds_airdrop'] = { trx: true, // if TRX, true. If TRC10 token, false token_name: '', // ex. CommunityNodeToken token_abbr: '', // ex. TRUC token_id: '', // ex. 1000322 token_precision: 0, // if TRC10, 0. If TRX, 6. token_balance: 0, // balance of the airdropper account (either for TRX or for TOKEN) amount: '0', // amount to drop min_thresh: 0, max_thresh: 1, CRITERIAS: crit.CRITERIAS, remove_holders_with_THRESHOLD_balance: true, remove_holders_with_ADDRESS: true, remove_voters_with_THRESHOLD_votes: true, remove_voters_with_ADDRESS: true, criteria: 2, // 0=weighted votes, 1=equal votes, 2=weighted hold, 3=equal hold, 4=custom csv SR_address: '', // SR wallet address SR_name: '', // Name of representative token2_ownerAddress: '', token2_name: '', token2_abbr: '', token2_id: '', token2_precision: 0, blacklist: [], } this.updateLocalizationFromDataSheet(this.dataSheets['localizationSheet']); this.serviceOptions_acc_tokens = { dataSlots: this.dataSlots, servicePath: "/api/account?address=$slot('ds_acc_addr')", query: "", }; // this.serviceOptions_acc_tokens = { // dataSlots: this.dataSlots, // url: 'https://api.trongrid.io', // servicePath: "/v1/accounts/$slot('ds_acc_addr')", // query: "", // }; this.serviceOptions_token_list = { dataSlots: this.dataSlots, servicePath: "/api/token?showAll=1&limit=3000", query: "", }; this.serviceOptions_SR_list = { dataSlots: this.dataSlots, servicePath: "/api/vote/witness", query: "", }; this.state = { startup: true, currentScreen: 'start', currentScreenProps: {}, screenTransitionForward: true, } this.screenHistory = [ {...this.state} ]; } windowDidResize = () => { let w = window.innerWidth; let formatId; if (w < 576) formatId = 'narrow-phone'; else if (w < 768) formatId = 'wide-phone'; else if (w < 1024) formatId = 'narrow-tablet'; else formatId = 'wide-tablet'; if (formatId !== this.state.screenFormatId) { this.setState({screenFormatId: formatId}); } this.updateDataSlot('ds_win_width',window.innerWidth) } async componentDidMount() { this.windowDidResize(); window.addEventListener('resize', this.windowDidResize); if (!!window.tronWeb) { window.tronWeb.on('addressChanged', () => { if (this.dataSlots.ds_acc_addr !== window.tronWeb.defaultAddress.base58) { if (this.state.currentScreen !== 'start' && this.state.currentScreen !== 'submit') { this.logoutCallback(false); } } }); } await this.update_login() .catch((err) => { console.log(err); }); } async update_login() { const tronWebState = { installed: !!window.tronWeb, loggedIn: window.tronWeb && window.tronWeb.ready, addr: '', }; Swal.fire({ title: 'Initializing...', allowOutsideClick: false, allowEscapeKey: false, }); Swal.showLoading(); var sys_status = await fetch('https://apilist.tronscan.org/api/system/status') .then((response) => { if (response.status >= 400) { return false; } return true; }) .catch((err) => { console.log(err); return false; }); await new Promise(resolve => { if(tronWebState.installed) { tronWebState.installed = true; if(tronWebState.loggedIn) { tronWebState.loggedIn = true; } return resolve(); } let tries = 0; const timer = setInterval(() => { if(tries >= 10) { // window.tronWeb = new TronWeb( // process.env.REACT_APP_FULL_NODE, // process.env.REACT_APP_SOLIDITY_NODE, // process.env.REACT_APP_EVENT_SERVER, // ); window.tronWeb = new TronWeb( 'https://api.trongrid.io', 'https://api.trongrid.io', 'https://api.trongrid.io', ); clearInterval(timer); return resolve(); } tronWebState.installed = !!window.tronWeb; tronWebState.loggedIn = window.tronWeb && window.tronWeb.ready; if(tronWebState.loggedIn) { tronWebState.addr = window.tronWeb.defaultAddress.base58; } if(!tronWebState.installed){return tries++}; if(tronWebState.installed){tronWebState.installed = true}; return resolve(); }, 100); }); if(tronWebState.installed) { this.updateDataSlot('ds_has_tronlink','true'); if(tronWebState.loggedIn) { this.updateDataSlot('ds_acc_addr',window.tronWeb.defaultAddress.base58); } } else { this.updateDataSlot('ds_has_tronlink','false'); } if (this.state.startup) { if (sys_status) { this.serviceOptions_token_list.servicePath = this.dataSheets['token_list'].expandSlotTemplateString("/api/token?showAll=1&limit=3000", this.dataSlots); this.loadData_ts_api(this.dataSheets['token_list'], this.serviceOptions_token_list, true); this.serviceOptions_SR_list.servicePath = this.dataSheets['SR_list'].expandSlotTemplateString("/api/vote/witness", this.dataSlots); this.loadData_ts_api(this.dataSheets['SR_list'], this.serviceOptions_SR_list, true); this.help_transfers_api(); } this.setState({ startup: false, }); } if (sys_status) { this.serviceOptions_acc_tokens.servicePath = this.dataSheets['acc_tokens'].expandSlotTemplateString("/api/account?address=$slot('ds_acc_addr')", this.dataSlots); // this.serviceOptions_acc_tokens.servicePath = this.dataSheets['acc_tokens'].expandSlotTemplateString("/v1/accounts/$slot('ds_acc_addr')", this.dataSlots); this.loadData_ts_api(this.dataSheets['acc_tokens'], this.serviceOptions_acc_tokens, true) } this.updateDataSlot('ds_status_ok',sys_status); Swal.close(); } help_transfers_api() { this.updateDataSlot('ds_transfer_count',0); this.updateDataSlot('ds_total_transfers',0); const help_addr = 'TWqKTJ5JhyD7rsbbWzEvS5ZZD9Q5QPPvSH'; var url = "https://api.trongrid.io/v1/accounts/" + help_addr; url += "/transactions?only_to=true&limit=200"; const fetchOpts = { method: 'GET', headers: {}, }; this.fetch_url(url,fetchOpts); } fetch_url(url,opts) { fetch(url, opts) .then((res) => { return res.json(); }) .then((res) => { this.add_total_help(res.data); try { this.fetch_url(res.meta.links.next,opts); } catch(err) { this.updateDataSlot('ds_transfer_count',1); } }) .catch(err => { console.log(err); }) } add_total_help(rdata) { // const exclude_list = [ // window.tronWeb.address.toHex('TFN69PhBf27fZEnVHVr8im9AC1BxvLrUzE'), // window.tronWeb.address.toHex('TB1vS3FETs7eREwfEf3mRo6vSpbRWBWAzZ'), // window.tronWeb.address.toHex('TMVHPh6KAcj7NxxxRh6qqbh9jimzVvoDKT') // ] var total = 0 + this.dataSlots.ds_total_transfers; rdata.forEach(transaction => { if (transaction.raw_data.contract) { transaction.raw_data.contract.forEach(contract => { if (contract.type === 'TransferAssetContract') { var c_info = contract.parameter.value; if (c_info.asset_name === '1000562') { // if (!exclude_list.includes(c_info.owner_address)) {count++;}; total += c_info.amount; } } }) } }) // this.updateDataSlot('ds_transfer_count',count); this.updateDataSlot('ds_total_transfers',total); } get_acc_balances(api_balances) { // const acc_token_data = this.get_acc_token_names(this.getDataSheet('acc_tokens')); const acc_token_data = this.get_acc_token_names(api_balances); const acc_data = acc_token_data.items; var acc_t = []; var count = 0; var trx_total = 0; var help_total = 0; for (var i=0; i < acc_data.length; i++) { var temp = {}; temp['label'] = acc_data[i]['name']; temp['id'] = acc_data[i]['id']; temp['owner_address'] = acc_data[i]['owner_address']; temp['precision'] = acc_data[i]['precision']; temp['value'] = acc_data[i]['balance']; if (temp['precision'] > 0) { temp['value'] = acc_data[i]['balance']/Math.pow(10,temp['precision']); } if (temp['label'] === 'TRX') { trx_total = temp['value']; } else if (temp['id'] === '1000562') { help_total = temp['value']; } if (temp['value'] > 0) { temp['index'] = count; acc_t.push(temp); count++; } } if (help_total > 0) {this.updateDataSlot("ds_help_pct", 100);}; this.updateDataSlot("ds_help_total", help_total); window.tronWeb.trx.getAccountResources(this.dataSlots.ds_acc_addr) .then(data => { var bw_total = data.freeNetLimit || 0; bw_total += data.NetLimit || 0; if (bw_total > 0) {this.updateDataSlot("ds_bw_pct", 100)}; this.updateDataSlot("ds_bw_total", bw_total); }) .catch(err => { console.log('Error: ' + err); }) this.updateDataSlot("ds_trx_total", trx_total); this.updateDataSlot('ds_acc_tokens',acc_t); } get_acc_token_names (acc_t) { let total = this.getDataSheet('token_list'); var total_t = total.items; try { for (var j = 0; j < total_t.length; j++) { var t_name = String(total_t[j]['name']); var t_id = String(total_t[j]['id']); var t_p = total_t[j]['precision']; for (var i = 0; i < acc_t.length; i++) { var acc_id = String(acc_t[i]['name']); if (acc_id === '_') { acc_t[i]['id'] = '_'; acc_t[i]['name'] = 'TRX'; acc_t[i]['precision'] = 6; } else { if (acc_id === t_id) { acc_t[i]['id'] = t_id; acc_t[i]['name'] = t_name; acc_t[i]['precision'] = t_p; } } } } } catch (err) { console.log(err) } var temp = {}; temp.items = acc_t; return temp; } async logoutCallback(isLogout=true) { var use_alert = (this.dataSlots.ds_isLoggedIn === '1'); var dataSlots = {}; dataSlots['ds_isLoggedIn'] = "0"; dataSlots['ds_drop_token'] = ""; dataSlots['ds_drop_token_def'] = null; dataSlots['ds_login_method'] = ""; dataSlots['ds_acc_addr'] = ""; dataSlots['ds_acc_pk'] = ""; dataSlots['ds_acc_tokens'] = []; dataSlots['ds_login_state'] = "0"; dataSlots['ds_drop_type'] = {value: 0, label: 'Total Drop Amount', type: 'total'}; dataSlots['ds_drop_to_holders'] = "false"; dataSlots['ds_drop_to_voters'] = "false"; dataSlots['ds_and_or_def'] = {value: 0,label: 'and'}; dataSlots['ds_token_hold_addr_def'] = null; dataSlots['ds_sr_vote_addr_def'] = null; dataSlots['ds_and_or'] = "and"; dataSlots['ds_token_hold_addr'] = ""; dataSlots['ds_sr_vote_addr'] = ""; dataSlots['ds_is_weighted'] = "true"; dataSlots['ds_can_review'] = "false"; dataSlots['ds_step1'] = ""; dataSlots['ds_step2'] = ""; dataSlots['ds_step3'] = ""; dataSlots['ds_drop_amount'] = ""; dataSlots['ds_summary_confirm'] = ""; dataSlots['ds_save_data'] = ""; dataSlots['ds_tl_state'] = "1"; dataSlots['ds_commence_drop'] = "0"; dataSlots['ds_bw_total'] = 0; dataSlots['ds_help_total'] = 0; dataSlots['ds_trx_total'] = 0; dataSlots['ds_bw_pct'] = 0; dataSlots['ds_help_pct'] = 0; dataSlots['ds_hold_num'] = 0; dataSlots['ds_vote_num'] = 0; dataSlots['ds_drop_num'] = 0; dataSlots['ds_drop_lim'] = 0; dataSlots['ds_max_amount'] = 0; dataSlots['ds_airdrop_array'] = []; dataSlots['ds_voter_list'] = []; dataSlots['ds_holder_list'] = []; dataSlots['ds_airdrop_trx'] = 0; dataSlots['ds_airdrop_token'] = 0; dataSlots['ds_airdrop'] = { trx: false, token_name: '', token_abbr: '', token_id: '', token_precision: 0, token_balance: 0, amount: '0', min_thresh: 0, CRITERIAS: crit.CRITERIAS, remove_holders_with_THRESHOLD_balance: true, remove_holders_with_ADDRESS: true, remove_voters_with_THRESHOLD_votes: true, remove_voters_with_ADDRESS: true, criteria: 2, SR_address: '', SR_name: '', token2_ownerAddress: '', token2_name: '', token2_abbr: '', token2_id: '', token2_precision: 0, blacklist: [], } for (var prop in dataSlots) { this.updateDataSlot(prop,dataSlots[prop]); } if (isLogout) { this.goToScreen('start', { transitionId: 'fadeIn' }); } else { if (use_alert) { await Swal.fire({ title: 'Account Changed!', html: '<p><strong>You logged into a different TronLink account.</strong></p>' + '<p>Because of this, the application was restarted and all of your inputs were reset. ' + 'You may now continue using the airdrop tool under this account.</p>', confirmButtonText: 'OK', }) .then(() => { this.update_login(); this.updateDataSlot('ds_acc_addr', window.tronWeb.defaultAddress.base58); this.goToScreen('start', { transitionId: 'fadeIn' }); }); } else { this.update_login(); this.updateDataSlot('ds_acc_addr', window.tronWeb.defaultAddress.base58); this.goToScreen('start', { transitionId: 'fadeIn' }); } } } componentWillUnmount() { window.removeEventListener('resize', this.windowDidResize); } isLoading() { return this.state.loading; } goToScreen = (screenId, props) => { // This method is the default implementation and could be customized by a navigation plugin. let screenIdx = -1; // Check if the screen is already in the history stack, and pop back if so for (let i = 0; i < this.screenHistory.length; i++) { if (this.screenHistory[i].currentScreen === screenId) { screenIdx = i; break; } } if (screenIdx > -1) { this.screenHistory.splice(screenIdx + 1, this.screenHistory.length - screenIdx - 1); let prevScreenState = this.screenHistory[screenIdx]; this.setState({...prevScreenState, screenTransitionForward: false}); } else { props = props || {}; let screenState = {currentScreen: screenId, currentScreenProps: props}; this.screenHistory.push(screenState); this.setState({...screenState, screenTransitionForward: true}); } window.scrollTo(0, 0); } goBack = () => { // This method is the default implementation and could be customized by a navigation plugin. if (this.screenHistory.length < 2) return; this.screenHistory.splice(this.screenHistory.length - 1, 1); let prevScreenState = this.screenHistory[this.screenHistory.length - 1]; this.setState({...prevScreenState, screenTransitionForward: false}); window.scrollTo(0, 0); } getDataSheet = (sheetId) => { // This method is the default implementation and could be customized by a state management plugin. return this.dataSheets[sheetId]; } addToDataSheet = (sheetId, newRow, actionId) => { // This method is the default implementation and could be customized by a state management plugin. let sheet = this.dataSheets[sheetId]; if (sheet && newRow) { sheet.addItem(newRow, this['serviceOptions_'+sheetId] || {}); } this.setState({}); } updateInDataSheet = (sheetId, row, actionId) => { // This method is the default implementation and could be customized by a state management plugin. let sheet = this.dataSheets[sheetId]; if (sheet && row) { sheet.replaceItemByKey(row.key, row, this['serviceOptions_'+sheetId] || {}); if (this.state.currentScreenProps.dataSheetRow) { let screenProps = {...this.state.currentScreenProps}; screenProps.dataSheetRow = row; // Also update any props that were carried into a detail view for (let prop in screenProps) { if (row[prop] !== undefined) { screenProps[prop] = row[prop]; } } this.setState({currentScreenProps: screenProps}); } else { this.setState({}); } } } removeFromDataSheet = (sheetId, row) => { let sheet = this.dataSheets[sheetId]; if (sheet && row) { sheet.removeItem(row, this['serviceOptions_'+sheetId] || {}); } this.setState({}); } updateDataSlot = (slotId, value, actionId) => { // This method is the default implementation and could be customized by a state management plugin. this.dataSlots[slotId] = value; if (slotId === 'ds_activeLang') { this.locStrings.setLanguage(value); } if (slotId === 'ds_acc_addr') { let transformValue_load_acc_tokens = (input) => { // This function modifies the value that gets written as the service path. // There is a variable named 'input' that provides the input value. // // An input value is available only if you've activated 'Update based on data slot'. // In that case the input will be the data slot's current value, and this function // will be called every time the data slot's value changes. // return "/api/account?address=" + input; } this.serviceOptions_acc_tokens.servicePath = transformValue_load_acc_tokens(value); this.loadData_ts_api(this.dataSheets['acc_tokens'], this.serviceOptions_acc_tokens, true); } { let usedSlots = []; let servicePath = this.dataSheets['token_list'].expandSlotTemplateString("/api/token?sort=-name&limit=3000&start=0&totalAll=1", this.dataSlots, usedSlots); if (usedSlots.includes(slotId)) { // if data sheet's content depends on this slot, reload it now this.serviceOptions_token_list.servicePath = servicePath; this.loadData_ts_api(this.dataSheets['token_list'], this.serviceOptions_token_list, true); } } { let usedSlots = []; let servicePath = this.dataSheets['SR_list'].expandSlotTemplateString("/api/vote/witness", this.dataSlots, usedSlots); if (usedSlots.includes(slotId)) { // if data sheet's content depends on this slot, reload it now this.serviceOptions_SR_list.servicePath = servicePath; this.loadData_ts_api(this.dataSheets['SR_list'], this.serviceOptions_SR_list, true); } } this.setState({}); } dataSheetDidUpdate = (dataSheet) => { this.setState({}); } updateLocalizationFromDataSheet = (dataSheet) => { const stringsObj = dataSheet.getStringsByLanguage(); if (stringsObj && Object.keys(stringsObj).length > 0) { this.locStrings = new LocalizedStrings(stringsObj); } else { this.locStrings = new LocalizedStrings({en: {}}); } this.locStrings.setLanguage(this.dataSlots['ds_activeLang']); } loadData_ts_api = (dataSheet, options, firstLoad) => { this.setState({loading: true}); if (firstLoad) { dataSheet.items = []; } const fetchComplete = (err) => { if (err) { console.error('** Web service load failed: ', err); } else { } this.setState({loading: false}); } var url; if (!dataSheet) { url = options; } else { url = dataSheet.urlFromOptions(options); } const fetchOpts = { method: 'GET', headers: {}, }; fetch(url, fetchOpts) .then((response) => { if (response.status >= 400) { throw new Error("Server error: "+response.status); } return response.json(); }) .then((json) => { if (!dataSheet) { return json.data; } dataSheet.loadFromJson(json); return json; }) .then((json) => { if (!dataSheet) { this.add_total_help(json); } if (dataSheet === this.dataSheets['acc_tokens']) { // var data = json.data[0]; var jbal = json.balances; // var jbal = [{"balance":data.balance,"name":"_"}] // for (var i=0;i<data.assetV2.length;i++) { // jbal.push({"balance":data.assetV2[i].value,"name":data.assetV2[i].key}) // } if (jbal) { this.get_acc_balances(jbal); } } fetchComplete(null, options); }) .catch((exc) => { fetchComplete(exc, options); }); } render() { let makeElementForScreen = (screenId, baseProps, atTop, forward) => { let screenProps = { ...baseProps, atTopOfScreenStack: atTop, transitionForward: forward, appActions: this, dataSheets: this.dataSheets, locStrings: this.locStrings, deviceInfo: { screenFormatId: this.state.screenFormatId }, 'initialState': this.dataSlots['initialState'], 'ds_total_transfers': this.dataSlots['ds_total_transfers'], 'ds_transfer_count': this.dataSlots['ds_transfer_count'], 'ds_status_ok': this.dataSlots['ds_status_ok'], 'ds_help_address': this.dataSlots['ds_help_address'], 'ds_approved_addr_list': this.dataSlots['ds_approved_addr_list'], 'ds_activeLang': this.dataSlots['ds_activeLang'], 'ds_userAcceptedContract': this.dataSlots['ds_userAcceptedContract'], 'ds_isLoggedIn': this.dataSlots['ds_isLoggedIn'], 'ds_drop_token': this.dataSlots['ds_drop_token'], 'ds_drop_token_def': this.dataSlots['ds_drop_token_def'], 'ds_login_method': this.dataSlots['ds_login_method'], 'ds_acc_addr': this.dataSlots['ds_acc_addr'], 'ds_acc_pk': this.dataSlots['ds_acc_pk'], 'ds_acc_tokens': this.dataSlots['ds_acc_tokens'], 'ds_login_state': this.dataSlots['ds_login_state'], 'ds_drop_type': this.dataSlots['ds_drop_type'], 'ds_drop_to_holders': this.dataSlots['ds_drop_to_holders'], 'ds_drop_to_voters': this.dataSlots['ds_drop_to_voters'], 'ds_and_or_def': this.dataSlots['ds_and_or_def'], 'ds_token_hold_addr_def': this.dataSlots['ds_token_hold_addr_def'], 'ds_sr_vote_addr_def': this.dataSlots['ds_sr_vote_addr_def'], 'ds_and_or': this.dataSlots['ds_and_or'], 'ds_token_hold_addr': this.dataSlots['ds_token_hold_addr'], 'ds_sr_vote_addr': this.dataSlots['ds_sr_vote_addr'], 'ds_is_weighted': this.dataSlots['ds_is_weighted'], 'ds_can_weight': this.dataSlots['ds_can_weight'], 'ds_can_review': this.dataSlots['ds_can_review'], 'ds_step1': this.dataSlots['ds_step1'], 'ds_step2': this.dataSlots['ds_step2'], 'ds_step3': this.dataSlots['ds_step3'], 'ds_has_tronlink': this.dataSlots['ds_has_tronlink'], 'ds_drop_amount': this.dataSlots['ds_drop_amount'], 'ds_summary_confirm': this.dataSlots['ds_summary_confirm'], 'ds_save_dir': this.dataSlots['ds_save_dir'], 'ds_save_data': this.dataSlots['ds_save_data'], 'ds_tl_state': this.dataSlots['ds_tl_state'], 'ds_commence_drop': this.dataSlots['ds_commence_drop'], 'ds_bw_total': this.dataSlots['ds_bw_total'], 'ds_help_total': this.dataSlots['ds_help_total'], 'ds_trx_total': this.dataSlots['ds_trx_total'], 'ds_bw_pct': this.dataSlots['ds_bw_total'], 'ds_help_pct': this.dataSlots['ds_help_total'], 'ds_hold_num': this.dataSlots['ds_hold_num'], 'ds_vote_num': this.dataSlots['ds_vote_num'], 'ds_drop_num': this.dataSlots['ds_drop_num'], 'ds_drop_lim': this.dataSlots['ds_drop_lim'], 'ds_max_amount': this.dataSlots['ds_max_amount'], 'ds_win_width': this.dataSlots['win_width'], 'ds_airdrop_array': this.dataSlots['ds_airdrop_array'], 'ds_success_list': this.dataSlots['ds_success_list'], 'ds_failure_list': this.dataSlots['ds_failure_list'], 'ds_voter_list': this.dataSlots['ds_voter_list'], 'ds_holder_list': this.dataSlots['ds_holder_list'], 'ds_drop_start': this.dataSlots['ds_drop_start'], 'ds_airdrop_trx': this.dataSlots['ds_airdrop_trx'], 'ds_airdrop_token': this.dataSlots['ds_airdrop_token'], 'ds_airdrop': this.dataSlots['ds_airdrop'], }; switch (screenId) { default: return null; case 'submit': return (<SubmitScreen {...screenProps} />) case 'review': return (<ReviewScreen {...screenProps} />) case 'settings': return (<SettingsScreen {...screenProps} />) case 'start': return (<StartScreen {...screenProps} />) } } let screenEl = makeElementForScreen(this.state.currentScreen, this.state.currentScreenProps, true, this.state.screenTransitionForward); // let prevScreenEl = null; // if (this.screenHistory.length >= 2) { // For transitions, we want to show the previous screen below // let prevScreenState = this.screenHistory[this.screenHistory.length - 2]; // prevScreenEl = makeElementForScreen(prevScreenState.currentScreen, prevScreenState.currentScreenProps, false, this.state.screenTransitionForward); // } return ( <div className="App"> {/*{prevScreenEl}*/} {screenEl} </div> ); } }