From b36cc417f5582f61247a46613355a60eba4c562a Mon Sep 17 00:00:00 2001 From: James Brown Date: Mon, 19 Feb 2024 17:43:10 +1100 Subject: [PATCH] Fix erc20 tokenscript (#3361) * Rework gas fetch methods * Display ERC20 correctly --- .../app/service/AssetDefinitionService.java | 54 ++---------- .../app/ui/AssetDisplayActivity.java | 2 +- .../app/ui/Erc20DetailActivity.java | 35 +++++--- .../alphawallet/app/ui/FunctionActivity.java | 2 +- .../com/alphawallet/app/ui/NFTActivity.java | 25 ------ .../app/ui/NFTAssetDetailActivity.java | 13 ++- .../alphawallet/app/ui/TokenInfoFragment.java | 56 +++++++++++- .../app/viewmodel/Erc20DetailViewModel.java | 29 ++++--- .../app/viewmodel/TokenFunctionViewModel.java | 13 --- .../alphawallet/app/web3/Web3TokenView.java | 34 ++------ .../main/res/layout/fragment_token_info.xml | 87 +++++++++++-------- .../token/entity/TSTokenViewHolder.java | 5 ++ .../alphawallet/token/entity/TicketRange.java | 25 ++++-- .../token/tools/TokenDefinition.java | 11 +-- 14 files changed, 200 insertions(+), 191 deletions(-) diff --git a/app/src/main/java/com/alphawallet/app/service/AssetDefinitionService.java b/app/src/main/java/com/alphawallet/app/service/AssetDefinitionService.java index 348e8858d9..2739528a7d 100644 --- a/app/src/main/java/com/alphawallet/app/service/AssetDefinitionService.java +++ b/app/src/main/java/com/alphawallet/app/service/AssetDefinitionService.java @@ -58,7 +58,6 @@ import com.alphawallet.token.entity.SigReturnType; import com.alphawallet.token.entity.TSAction; import com.alphawallet.token.entity.TSSelection; -import com.alphawallet.token.entity.TSTokenView; import com.alphawallet.token.entity.TokenScriptResult; import com.alphawallet.token.entity.TokenscriptContext; import com.alphawallet.token.entity.TokenscriptElement; @@ -210,7 +209,7 @@ private void loadAssetScripts() Timber.e(e); } - List handledHashes = checkRealmScriptsForChanges(); + //List handledHashes = checkRealmScriptsForChanges(); //loadNewFiles(handledHashes); //executes after observable completes due to blockingForEach @@ -1203,6 +1202,7 @@ private TokenDefinition parseFile(InputStream xmlInputStream) throws Exception private Single handleNewTSFile(File newFile) { + //if unchanged return existing definition if (!newFile.exists()) { return signalUnchangedScript(newFile.getName()); @@ -2176,12 +2176,6 @@ public boolean hasDefinition(Token token) return hasDefinition; } - //when user reloads the tokens we should also check XML for any files - public void clearCheckTimes() - { - assetChecked.clear(); - } - public boolean hasTokenView(Token token, String type) { try (Realm realm = realmManager.getRealmInstance(ASSET_DEFINITION_DB)) @@ -2194,43 +2188,6 @@ public boolean hasTokenView(Token token, String type) } } - public TSTokenView getTSTokenView(Token token, String type) - { - TokenDefinition td = getAssetDefinition(token); - if (td != null) - { - return td.getTSTokenView(type); - } - else - { - return null; - } - } - - public String getTokenView(Token token, String type) - { - String viewHTML = ""; - TokenDefinition td = getAssetDefinition(token); - if (td != null) - { - viewHTML = td.getTokenView(type); - } - - return viewHTML; - } - - public String getTokenViewStyle(Token token, String type) - { - String styleData = ""; - TokenDefinition td = getAssetDefinition(token); - if (td != null) - { - styleData = td.getTokenViewStyle(type); - } - - return styleData; - } - public List getTokenViewLocalAttributes(Token token) { TokenDefinition td = getAssetDefinition(token); @@ -2312,6 +2269,9 @@ public Single>> fetchFunctionMap(Token token, @NotN Map> attrResults // Map of attribute results vs tokenId = getRequiredAttributeResults(requiredAttrNames, tokenIds, td, token, update); // Map of all required attribute values vs all the tokenIds + //What about for ERC20? + //ERC20! + for (BigInteger tokenId : tokenIds) { for (String actionName : actions.keySet()) @@ -2741,7 +2701,7 @@ private void addOpenSeaAttributes(StringBuilder attrs, Token token, BigInteger t } } - public StringBuilder getTokenAttrs(Token token, BigInteger tokenId, int count) + public StringBuilder getTokenAttrs(Token token, BigInteger tokenId, BigInteger count) { StringBuilder attrs = new StringBuilder(); @@ -2754,7 +2714,7 @@ public StringBuilder getTokenAttrs(Token token, BigInteger tokenId, int count) TokenScriptResult.addPair(attrs, "name", token.tokenInfo.name); TokenScriptResult.addPair(attrs, "label", label); TokenScriptResult.addPair(attrs, "symbol", token.getSymbol()); - TokenScriptResult.addPair(attrs, "_count", BigInteger.valueOf(count)); + TokenScriptResult.addPair(attrs, "_count", count.toString()); TokenScriptResult.addPair(attrs, "contractAddress", token.tokenInfo.address); TokenScriptResult.addPair(attrs, "chainId", BigInteger.valueOf(token.tokenInfo.chainId)); TokenScriptResult.addPair(attrs, "tokenId", tokenId); diff --git a/app/src/main/java/com/alphawallet/app/ui/AssetDisplayActivity.java b/app/src/main/java/com/alphawallet/app/ui/AssetDisplayActivity.java index 1c9c46deae..f619189eec 100644 --- a/app/src/main/java/com/alphawallet/app/ui/AssetDisplayActivity.java +++ b/app/src/main/java/com/alphawallet/app/ui/AssetDisplayActivity.java @@ -213,7 +213,7 @@ private void initWebViewCheck(TokenDefinition td) BigInteger tokenId = token.getArrayBalance().get(0); TicketRange data = new TicketRange(tokenId, token.getAddress()); testView.setChainId(token.tokenInfo.chainId); - testView.renderTokenScriptView(token, data, viewModel.getAssetDefinitionService(), ViewType.ITEM_VIEW, td); + testView.renderTokenScriptInfoView(token, data, viewModel.getAssetDefinitionService(), ViewType.ITEM_VIEW, td); testView.setOnReadyCallback(this); } else diff --git a/app/src/main/java/com/alphawallet/app/ui/Erc20DetailActivity.java b/app/src/main/java/com/alphawallet/app/ui/Erc20DetailActivity.java index c22994dd96..4ca127cf11 100644 --- a/app/src/main/java/com/alphawallet/app/ui/Erc20DetailActivity.java +++ b/app/src/main/java/com/alphawallet/app/ui/Erc20DetailActivity.java @@ -5,6 +5,7 @@ import static com.alphawallet.app.repository.TokensRealmSource.databaseKey; import static com.alphawallet.app.ui.MyAddressActivity.KEY_MODE; import static com.alphawallet.ethereum.EthereumNetworkBase.MAINNET_ID; +import static com.alphawallet.token.tools.TokenDefinition.UNCHANGED_SCRIPT; import android.content.Context; import android.content.Intent; @@ -49,6 +50,7 @@ import com.alphawallet.app.widget.CertifiedToolbarView; import com.alphawallet.app.widget.FunctionButtonBar; import com.alphawallet.token.entity.XMLDsigDescriptor; +import com.alphawallet.token.tools.TokenDefinition; import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; @@ -56,6 +58,7 @@ import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import dagger.hilt.android.AndroidEntryPoint; @@ -79,6 +82,8 @@ public class Erc20DetailActivity extends BaseActivity implements StandardFunctio private ActivityHistoryList activityHistoryList = null; private Realm realm = null; private RealmResults realmTokenUpdates; + private CertifiedToolbarView certHeader; + private final TokenInfoFragment tokenInfoFragment = new TokenInfoFragment(); private ViewPager2 viewPager; @@ -100,7 +105,7 @@ public Pair init(Context context, Bundle bundle) } private final DetailPage[] detailPages = new DetailPage[] { - new DetailPage(R.string.tab_info, new TokenInfoFragment()), + new DetailPage(R.string.tab_info, tokenInfoFragment), new DetailPage(R.string.tab_activity, new TokenActivityFragment()), new DetailPage(R.string.tab_alert, new TokenAlertsFragment()) }; @@ -126,6 +131,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) getIntentData(); } + certHeader = findViewById(R.id.certified_toolbar); + certHeader.startDownload(); viewModel.checkForNewScript(token); setTitle(token.tokenInfo.name + " (" + token.tokenInfo.symbol + ")"); @@ -190,8 +197,8 @@ private void setupButtons() if (BuildConfig.DEBUG || wallet.type != WalletType.WATCH) { FunctionButtonBar functionBar = findViewById(R.id.layoutButtons); + functionBar.setupFunctions(this, viewModel.getAssetDefinitionService(), token, null, Collections.singletonList(BigInteger.ZERO)); functionBar.setupBuyFunction(this, viewModel.getOnRampRepository()); - functionBar.setupFunctions(this, viewModel.getAssetDefinitionService(), token, null, null); functionBar.revealButtons(); functionBar.setWalletType(wallet.type); } @@ -203,10 +210,9 @@ private void setupViewModel() { viewModel = new ViewModelProvider(this) .get(Erc20DetailViewModel.class); - viewModel.newScriptFound().observe(this, this::onNewScript); + viewModel.newScriptFound().observe(this, this::newScriptFound); viewModel.sig().observe(this, this::onSignature); viewModel.scriptUpdateInProgress().observe(this, this::startScriptDownload); -// findViewById(R.id.certificate_spinner).setVisibility(View.VISIBLE); //Samoa TODO: restore certificate toolbar } } @@ -225,16 +231,27 @@ private void startScriptDownload(Boolean status) } } - private void onNewScript(Boolean hasNewScript) + private void newScriptFound(TokenDefinition td) { + //determinate signature + certHeader.stopDownload(); + certHeader.setVisibility(View.VISIBLE); + final TokenGroup group = viewModel.getTokensService().getTokenGroup(token); //found a new tokenscript for this token, create a new meta with balance set to trigger view update; view will update the token name tokenViewAdapter.updateToken(new TokenCardMeta(token.tokenInfo.chainId, token.getAddress(), "force_update", token.updateBlancaTime, token.lastTxCheck, token.getInterfaceSpec(), group)); - viewModel.checkTokenScriptValidity(token); //check script signature - CertifiedToolbarView certificateToolbar = findViewById(R.id.certified_toolbar); - certificateToolbar.stopDownload(); + setupButtons(); + + if (td.nameSpace.equals(UNCHANGED_SCRIPT)) + { + td = viewModel.getAssetDefinitionService().getAssetDefinition(token); + } + + //new script, need to check validity + viewModel.checkTokenScriptValidity(token); //check script signature + tokenInfoFragment.initTokenScript(td); } private void onSignature(XMLDsigDescriptor descriptor) @@ -274,7 +291,6 @@ public boolean canScrollVertically() tokenView.setAdapter(tokenViewAdapter); setTokenListener(); setupButtons(); - viewModel.checkTokenScriptValidity(token); } private void getIntentData() @@ -288,7 +304,6 @@ private void getIntentData() token = viewModel.getTokensService().getTokenOrBase(chainId, getIntent().getStringExtra(C.EXTRA_ADDRESS)); token.group = viewModel.getTokensService().getTokenGroup(token); tokenMeta = new TokenCardMeta(token, token.getName()); - viewModel.checkForNewScript(token); } @Override diff --git a/app/src/main/java/com/alphawallet/app/ui/FunctionActivity.java b/app/src/main/java/com/alphawallet/app/ui/FunctionActivity.java index 055ff7b9cd..1121a3eb57 100644 --- a/app/src/main/java/com/alphawallet/app/ui/FunctionActivity.java +++ b/app/src/main/java/com/alphawallet/app/ui/FunctionActivity.java @@ -197,7 +197,7 @@ private void getAttrs() { try { - attrs = viewModel.getAssetDefinitionService().getTokenAttrs(token, tokenId, 1); + attrs = viewModel.getAssetDefinitionService().getTokenAttrs(token, tokenId, BigInteger.ONE); //add extra tokenIds if required addMultipleTokenIds(attrs); } diff --git a/app/src/main/java/com/alphawallet/app/ui/NFTActivity.java b/app/src/main/java/com/alphawallet/app/ui/NFTActivity.java index 4c6694ff6a..54463e75da 100644 --- a/app/src/main/java/com/alphawallet/app/ui/NFTActivity.java +++ b/app/src/main/java/com/alphawallet/app/ui/NFTActivity.java @@ -51,7 +51,6 @@ public class NFTActivity extends BaseActivity implements StandardFunctionInterfa private NFTViewModel viewModel; private Wallet wallet; private Token token; - private FunctionButtonBar functionBar; private boolean isGridView; private MenuItem sendMultipleTokensMenuItem; private MenuItem switchToGridViewMenuItem; @@ -241,11 +240,9 @@ public void onTabSelected(TabLayout.Tab tab) switch (tab.getPosition()) { case 0: - // showFunctionBar(true); showMenu(); break; default: - // showFunctionBar(false); hideMenu(); break; } @@ -265,16 +262,6 @@ public void onTabReselected(TabLayout.Tab tab) }); } - private void showFunctionBar(boolean show) - { - if (functionBar == null && !show) return; - if (BuildConfig.DEBUG || wallet.type != WalletType.WATCH) - { - if (functionBar == null) setupFunctionBar(); - functionBar.setVisibility(show ? View.VISIBLE : View.GONE); - } - } - @Override public boolean onPrepareOptionsMenu(Menu menu) { @@ -346,18 +333,6 @@ public void onDestroy() viewModel.onDestroy(); } - private void setupFunctionBar() - { - if (BuildConfig.DEBUG || wallet.type != WalletType.WATCH) - { - functionBar = findViewById(R.id.layoutButtons); - functionBar.setupFunctions(this, viewModel.getAssetDefinitionService(), token, null, null); - functionBar.revealButtons(); - functionBar.setWalletType(wallet.type); - functionBar.setVisibility(View.GONE); - } - } - private void hideMenu() { if (sendMultipleTokensMenuItem != null) diff --git a/app/src/main/java/com/alphawallet/app/ui/NFTAssetDetailActivity.java b/app/src/main/java/com/alphawallet/app/ui/NFTAssetDetailActivity.java index 47507e9423..9998f3838e 100644 --- a/app/src/main/java/com/alphawallet/app/ui/NFTAssetDetailActivity.java +++ b/app/src/main/java/com/alphawallet/app/ui/NFTAssetDetailActivity.java @@ -34,7 +34,6 @@ import com.alphawallet.app.entity.GasEstimate; import com.alphawallet.app.entity.SignAuthenticationCallback; import com.alphawallet.app.entity.StandardFunctionInterface; -import com.alphawallet.app.entity.TSAttrCallback; import com.alphawallet.app.entity.TransactionReturn; import com.alphawallet.app.entity.Wallet; import com.alphawallet.app.entity.WalletType; @@ -75,6 +74,7 @@ import dagger.hilt.android.AndroidEntryPoint; import io.reactivex.functions.Consumer; +import timber.log.Timber; @AndroidEntryPoint public class NFTAssetDetailActivity extends BaseActivity implements StandardFunctionInterface, ActionSheetCallback @@ -851,11 +851,19 @@ private boolean displayTokenView(final TokenDefinition td) try { LinearLayout webWrapper = findViewById(R.id.layout_webwrapper); + //restart if required + if (tokenScriptView != null) + { + webWrapper.removeView(tokenScriptView); + tokenScriptView.destroy(); + tokenScriptView = null; + } + tokenScriptView = new Web3TokenView(this); tokenScriptView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); tokenScriptView.clearCache(true); - if (tokenScriptView.renderTokenScriptView(token, new TicketRange(tokenId, token.getAddress()), viewModel.getAssetDefinitionService(), ViewType.VIEW, td)) + if (tokenScriptView.renderTokenScriptInfoView(token, new TicketRange(tokenId, token.getAddress()), viewModel.getAssetDefinitionService(), ViewType.VIEW, td)) { webWrapper.setVisibility(View.VISIBLE); tokenScriptView.setChainId(token.tokenInfo.chainId); @@ -866,6 +874,7 @@ private boolean displayTokenView(final TokenDefinition td) } catch (Exception e) { + Timber.e(e); //fillEmpty(); } diff --git a/app/src/main/java/com/alphawallet/app/ui/TokenInfoFragment.java b/app/src/main/java/com/alphawallet/app/ui/TokenInfoFragment.java index e1f02f3bd8..e7e2062556 100644 --- a/app/src/main/java/com/alphawallet/app/ui/TokenInfoFragment.java +++ b/app/src/main/java/com/alphawallet/app/ui/TokenInfoFragment.java @@ -16,7 +16,6 @@ import androidx.annotation.Nullable; import androidx.lifecycle.ViewModelProvider; -import com.alphawallet.app.BuildConfig; import com.alphawallet.app.C; import com.alphawallet.app.R; import com.alphawallet.app.entity.tokens.Token; @@ -25,11 +24,16 @@ import com.alphawallet.app.ui.widget.entity.HistoryChart; import com.alphawallet.app.util.TabUtils; import com.alphawallet.app.viewmodel.TokenInfoViewModel; +import com.alphawallet.app.web3.Web3TokenView; +import com.alphawallet.app.web3.entity.Address; import com.alphawallet.app.widget.TokenInfoCategoryView; import com.alphawallet.app.widget.TokenInfoHeaderView; import com.alphawallet.app.widget.TokenInfoView; import com.alphawallet.ethereum.EthereumNetworkBase; +import com.alphawallet.token.entity.TicketRange; +import com.alphawallet.token.entity.ViewType; import com.alphawallet.token.tools.Convert; +import com.alphawallet.token.tools.TokenDefinition; import com.google.android.material.tabs.TabLayout; import org.json.JSONArray; @@ -43,8 +47,6 @@ import java.util.TimeZone; import java.util.concurrent.TimeUnit; -import javax.inject.Inject; - import dagger.hilt.android.AndroidEntryPoint; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -85,6 +87,8 @@ public class TokenInfoFragment extends BaseFragment { private TokenInfoView stats1YearLow; private TokenInfoView stats1YearHigh; private TokenInfoView contractAddress; + private LinearLayout webWrapper; + private Web3TokenView tokenScriptView; @Nullable @Override @@ -109,6 +113,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat historyChart = view.findViewById(R.id.history_chart); tokenInfoHeaderLayout = view.findViewById(R.id.layout_token_header); tokenInfoLayout = view.findViewById(R.id.layout_token_info); + webWrapper = view.findViewById(R.id.layout_webwrapper); //TODO: Work out how to source these //portfolioBalance = new TokenInfoView(getContext(), "Balance"); @@ -386,4 +391,49 @@ private Date getMidnightDateFromTimestamp(long timeStampInMillis) { calendar.set(Calendar.HOUR_OF_DAY, 0); return calendar.getTime(); } + + @Override + public void onDestroy() + { + if (tokenScriptView != null && tokenScriptView.getVisibility() == View.VISIBLE) + { + webWrapper.removeView(tokenScriptView); + tokenScriptView.destroy(); + tokenScriptView = null; + } + super.onDestroy(); + } + + /*** + * TokenScript view handling + */ + public void initTokenScript(final TokenDefinition td) + { + try + { + //restart if required + if (tokenScriptView != null) + { + webWrapper.removeView(tokenScriptView); + tokenScriptView.destroy(); + tokenScriptView = null; + } + + tokenScriptView = new Web3TokenView(requireContext()); + tokenScriptView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + tokenScriptView.clearCache(true); + + if (tokenScriptView.renderTokenScriptInfoView(token, new TicketRange(token.balance.toBigInteger()), viewModel.getAssetDefinitionService(), ViewType.VIEW, td)) + { + webWrapper.setVisibility(View.VISIBLE); + tokenScriptView.setChainId(token.tokenInfo.chainId); + tokenScriptView.setWalletAddress(new Address(token.getWallet())); + webWrapper.addView(tokenScriptView); + } + } + catch (Exception e) + { + //fillEmpty(); + } + } } diff --git a/app/src/main/java/com/alphawallet/app/viewmodel/Erc20DetailViewModel.java b/app/src/main/java/com/alphawallet/app/viewmodel/Erc20DetailViewModel.java index d3893af46a..5e0819a93f 100644 --- a/app/src/main/java/com/alphawallet/app/viewmodel/Erc20DetailViewModel.java +++ b/app/src/main/java/com/alphawallet/app/viewmodel/Erc20DetailViewModel.java @@ -1,5 +1,8 @@ package com.alphawallet.app.viewmodel; +import static com.alphawallet.token.tools.TokenDefinition.NO_SCRIPT; +import static com.alphawallet.token.tools.TokenDefinition.UNCHANGED_SCRIPT; + import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -34,9 +37,8 @@ @HiltViewModel public class Erc20DetailViewModel extends BaseViewModel { - private final MutableLiveData transactions = new MutableLiveData<>(); private final MutableLiveData sig = new MutableLiveData<>(); - private final MutableLiveData newScriptFound = new MutableLiveData<>(); + private final MutableLiveData newScriptFound = new MutableLiveData<>(); private final MutableLiveData scriptUpdateInProgress = new MutableLiveData<>(); private final MyAddressRouter myAddressRouter; @@ -69,7 +71,7 @@ public LiveData sig() return sig; } - public LiveData newScriptFound() + public LiveData newScriptFound() { return newScriptFound; } @@ -138,18 +140,23 @@ public void checkForNewScript(Token token) scriptUpdate = assetDefinitionService.checkServerForScript(token, scriptUpdateInProgress) .observeOn(Schedulers.io()) .subscribeOn(Schedulers.single()) - .subscribe(this::handleFilename, e -> scriptUpdateInProgress.postValue(false)); + .subscribe(this::handleDefinition, e -> scriptUpdateInProgress.postValue(false)); } - private void handleFilename(TokenDefinition td) + private void handleDefinition(TokenDefinition td) { - if (!TextUtils.isEmpty(td.holdingToken)) - { - newScriptFound.postValue(true); - } - else + switch (td.nameSpace) { - scriptUpdateInProgress.postValue(false); + case UNCHANGED_SCRIPT: + td.nameSpace = UNCHANGED_SCRIPT; + newScriptFound.postValue(td); + break; + case NO_SCRIPT: + scriptUpdateInProgress.postValue(false); + break; + default: + newScriptFound.postValue(td); + break; } } diff --git a/app/src/main/java/com/alphawallet/app/viewmodel/TokenFunctionViewModel.java b/app/src/main/java/com/alphawallet/app/viewmodel/TokenFunctionViewModel.java index a1c81fe785..9cda86cbce 100644 --- a/app/src/main/java/com/alphawallet/app/viewmodel/TokenFunctionViewModel.java +++ b/app/src/main/java/com/alphawallet/app/viewmodel/TokenFunctionViewModel.java @@ -319,19 +319,6 @@ public String getTransactionBytes(Token token, BigInteger tokenId, FunctionDefin return assetDefinitionService.generateTransactionPayload(token, tokenId, def); } - public TokenScriptResult getTokenScriptResult(Token token, BigInteger tokenId) - { - return assetDefinitionService.getTokenScriptResult(token, tokenId); - } - - public BigInteger calculateMinGasPrice(BigInteger oldGasPrice) - { - //get 0.1GWEI in wei - BigInteger zeroPointOneWei = BalanceUtils.gweiToWei(BigDecimal.valueOf(0.1)); - return new BigDecimal(oldGasPrice).multiply(BigDecimal.valueOf(1.1)).setScale(18, RoundingMode.UP).toBigInteger() - .add(zeroPointOneWei); - } - public Token getToken(long chainId, String contractAddress) { return tokensService.getToken(chainId, contractAddress); diff --git a/app/src/main/java/com/alphawallet/app/web3/Web3TokenView.java b/app/src/main/java/com/alphawallet/app/web3/Web3TokenView.java index 5de22e1b2f..cefed93664 100644 --- a/app/src/main/java/com/alphawallet/app/web3/Web3TokenView.java +++ b/app/src/main/java/com/alphawallet/app/web3/Web3TokenView.java @@ -1,7 +1,5 @@ package com.alphawallet.app.web3; -import static com.alphawallet.app.service.AssetDefinitionService.ASSET_DETAIL_VIEW_NAME; -import static com.alphawallet.app.service.AssetDefinitionService.ASSET_SUMMARY_VIEW_NAME; import static com.alphawallet.token.tools.TokenDefinition.TOKENSCRIPT_ERROR; import android.annotation.SuppressLint; @@ -29,14 +27,12 @@ import com.alphawallet.app.BuildConfig; import com.alphawallet.app.R; -import com.alphawallet.app.entity.StandardFunctionInterface; import com.alphawallet.app.entity.UpdateType; import com.alphawallet.app.entity.tokens.Token; import com.alphawallet.app.entity.tokenscript.TokenScriptRenderCallback; import com.alphawallet.app.entity.tokenscript.WebCompletionCallback; import com.alphawallet.app.repository.entity.RealmAuxData; import com.alphawallet.app.service.AssetDefinitionService; -import com.alphawallet.app.util.Utils; import com.alphawallet.app.web3.entity.Address; import com.alphawallet.app.web3.entity.FunctionCallback; import com.alphawallet.app.web3.entity.PageReadyCallback; @@ -51,8 +47,6 @@ import org.jetbrains.annotations.NotNull; -import java.io.LineNumberReader; -import java.io.StringReader; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.Map; @@ -405,7 +399,7 @@ private void renderTicketHolder(Token token, TokenDefinition td, TicketRange ran if (td != null && td.holdingToken != null) { //use webview - renderTokenScriptView(token, range, assetService, iconified, td); + renderTokenScriptInfoView(token, range, assetService, iconified, td); } else { @@ -429,24 +423,25 @@ private void showLegacyView(Token token, TicketRange range) loadData(displayData, "text/html", "utf-8"); } - public boolean renderTokenScriptView(Token token, TicketRange range, AssetDefinitionService assetService, ViewType itemView, + public boolean renderTokenScriptInfoView(Token token, TicketRange range, AssetDefinitionService assetService, ViewType itemView, final TokenDefinition td) { BigInteger tokenId = range.tokenIds.get(0); - if (!td.hasTokenView()) + TSTokenView tokenView = td.getTSTokenView("Info"); + if (tokenView == null) { return false; } attrResults = ""; - final StringBuilder attrs = assetService.getTokenAttrs(token, tokenId, range.tokenIds.size()); + final StringBuilder attrs = assetService.getTokenAttrs(token, tokenId, range.balance); buildViewAttrs = assetService.resolveAttrs(token, null, tokenId, assetService.getTokenViewLocalAttributes(token), itemView, UpdateType.USE_CACHE) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(attr -> onAttr(attr, attrs), throwable -> onError(token, throwable, range), - () -> displayTokenView(token, assetService, attrs, itemView, range, td)); + () -> displayTokenView(token, assetService, attrs, itemView, range, td, tokenView)); return true; } @@ -459,27 +454,14 @@ public boolean renderTokenScriptView(Token token, TicketRange range, AssetDefini * @param iconified * @param range */ - private void displayTokenView(Token token, AssetDefinitionService assetService, StringBuilder attrs, ViewType iconified, TicketRange range, final TokenDefinition td) + private void displayTokenView(Token token, AssetDefinitionService assetService, StringBuilder attrs, ViewType iconified, TicketRange range, final TokenDefinition td, final TSTokenView tokenView) { setVisibility(View.VISIBLE); - String viewName; - switch (iconified) - { - case VIEW: - default: - viewName = ASSET_DETAIL_VIEW_NAME; - break; - case ITEM_VIEW: - viewName = ASSET_SUMMARY_VIEW_NAME; - break; - } - - TSTokenView tokenView = td.getTSTokenView(viewName); String view = tokenView.getTokenView(); if (TextUtils.isEmpty(view)) { - view = buildViewError(token, range, viewName); + view = buildViewError(token, range, tokenView.getLabel()); } String style = tokenView.getStyle(); unencodedPage = injectWeb3TokenInit(view, attrs.toString(), range.tokenIds.get(0)); diff --git a/app/src/main/res/layout/fragment_token_info.xml b/app/src/main/res/layout/fragment_token_info.xml index 03c90c60a8..da10507387 100644 --- a/app/src/main/res/layout/fragment_token_info.xml +++ b/app/src/main/res/layout/fragment_token_info.xml @@ -1,60 +1,79 @@ - - - + android:layout_height="match_parent"> - + android:layout_marginBottom="?actionBarSize" + android:orientation="vertical"> + + + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + android:id="@+id/placeholder" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/ic_components_charts_graph_stable" + android:visibility="invisible" /> + android:id="@+id/history_chart" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + android:id="@+id/tab_layout" + style="@style/Aw.Component.ChartTabLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" /> + style="@style/Aw.Component.Separator" + android:layout_marginStart="@dimen/tiny_8" + android:layout_marginTop="@dimen/tiny_8" + android:layout_marginEnd="@dimen/tiny_8" /> + android:id="@+id/layout_token_info" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" /> + + + + + diff --git a/lib/src/main/java/com/alphawallet/token/entity/TSTokenViewHolder.java b/lib/src/main/java/com/alphawallet/token/entity/TSTokenViewHolder.java index c8ab514536..9d9b44a98d 100644 --- a/lib/src/main/java/com/alphawallet/token/entity/TSTokenViewHolder.java +++ b/lib/src/main/java/com/alphawallet/token/entity/TSTokenViewHolder.java @@ -41,4 +41,9 @@ private TSTokenView getViewOrDefault(String viewName) return v; } + + public TSTokenView getTSView(String name) + { + return getViewOrDefault(name); + } } diff --git a/lib/src/main/java/com/alphawallet/token/entity/TicketRange.java b/lib/src/main/java/com/alphawallet/token/entity/TicketRange.java index 06e3264142..c039c03812 100644 --- a/lib/src/main/java/com/alphawallet/token/entity/TicketRange.java +++ b/lib/src/main/java/com/alphawallet/token/entity/TicketRange.java @@ -2,6 +2,7 @@ import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -18,7 +19,17 @@ public class TicketRange public boolean exposeRadio; public String contractAddress; // Should this be address or actual token? - public List tokenIds; + public final List tokenIds; + public final BigInteger balance; //in wei for ERC20 + public final boolean isERC20; + + public TicketRange(BigInteger balance) + { + this.balance = balance; + this.isERC20 = true; + this.tokenIds = new ArrayList<>(Collections.singleton(BigInteger.ZERO)); + this.contractAddress = null; + } public TicketRange(BigInteger tokenId, String contractAddress) { @@ -27,6 +38,8 @@ public TicketRange(BigInteger tokenId, String contractAddress) tokenIds.add(tokenId); this.isChecked = false; this.exposeRadio = false; + this.balance = BigInteger.ONE; + this.isERC20 = false; } public TicketRange(List tokenIds, String contractAddress, boolean isChecked) @@ -35,14 +48,8 @@ public TicketRange(List tokenIds, String contractAddress, boolean is this.tokenIds = tokenIds; this.isChecked = isChecked; this.exposeRadio = false; - } - - public void selectSubRange(int count) - { - if (count < tokenIds.size()) - { - tokenIds = tokenIds.subList(0, count); - } + this.balance = BigInteger.valueOf(tokenIds.size()); + this.isERC20 = false; } public boolean equals(TicketRange compare) diff --git a/lib/src/main/java/com/alphawallet/token/tools/TokenDefinition.java b/lib/src/main/java/com/alphawallet/token/tools/TokenDefinition.java index 9f1bf0fb51..8fda51a6cd 100644 --- a/lib/src/main/java/com/alphawallet/token/tools/TokenDefinition.java +++ b/lib/src/main/java/com/alphawallet/token/tools/TokenDefinition.java @@ -38,7 +38,6 @@ import org.web3j.abi.datatypes.Utf8String; import org.web3j.abi.datatypes.generated.Bytes32; import org.web3j.abi.datatypes.generated.Uint256; -import org.web3j.utils.Numeric; import org.xml.sax.SAXException; import java.io.IOException; @@ -1735,15 +1734,9 @@ public String getTokenView(String viewTag) return tokenViews.getView(viewTag); } - public TSTokenView getTSTokenView(String type) + public TSTokenView getTSTokenView(String name) { - TSTokenView view = tokenViews.views.get(type); - if (view == null && tokenViews.views.size() > 0) - { - view = tokenViews.views.values().iterator().next(); - } - - return view; + return tokenViews.getTSView(name); } public String getTokenViewStyle(String viewTag)