package com.yoghurt.crypto.transactions.client.ui; import com.google.gwt.core.client.GWT; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; import com.googlecode.gwt.crypto.bouncycastle.util.encoders.Hex; import com.yoghurt.crypto.transactions.client.di.BitcoinPlaceRouter; import com.yoghurt.crypto.transactions.client.i18n.M; import com.yoghurt.crypto.transactions.client.util.FormatUtil; import com.yoghurt.crypto.transactions.client.util.TextConversionUtil; import com.yoghurt.crypto.transactions.client.util.transaction.TransactionEncodeUtil; import com.yoghurt.crypto.transactions.client.widget.BlockViewer; import com.yoghurt.crypto.transactions.client.widget.HashHexViewer; import com.yoghurt.crypto.transactions.client.widget.LabelledWidget; import com.yoghurt.crypto.transactions.client.widget.TransactionHexViewer; import com.yoghurt.crypto.transactions.client.widget.TransactionInputWidget; import com.yoghurt.crypto.transactions.client.widget.TransactionOutputWidget; import com.yoghurt.crypto.transactions.client.widget.ValueViewer; import com.yoghurt.crypto.transactions.shared.domain.RawTransactionContainer; import com.yoghurt.crypto.transactions.shared.domain.Transaction; import com.yoghurt.crypto.transactions.shared.domain.TransactionInformation; import com.yoghurt.crypto.transactions.shared.domain.TransactionInput; import com.yoghurt.crypto.transactions.shared.domain.TransactionOutput; import com.yoghurt.crypto.transactions.shared.domain.TransactionPartType; import com.yoghurt.crypto.transactions.shared.domain.TransactionState; public class TransactionViewImpl extends Composite implements TransactionView { interface TransactionViewImplUiBinder extends UiBinder<Widget, TransactionViewImpl> {} private static final TransactionViewImplUiBinder UI_BINDER = GWT.create(TransactionViewImplUiBinder.class); // Widgets relating to showing which content (error/info) @UiField FlowPanel errorView; @UiField Label transactionFullBlownErrorLabel; @UiField FlowPanel fullTransactionInformation; @UiField Label notFoundLabel; // General information @UiField HashHexViewer txIdViewer; // Widgets related to extra (blockchain information) @UiField FlowPanel extraInformationContainer; @UiField ValueViewer txStateViewer; @UiField LabelledWidget txBlockContainer; @UiField(provided = true) BlockViewer txBlockViewer; @UiField LabelledWidget txConfirmationsContainer; @UiField ValueViewer txConfirmationsViewer; @UiField LabelledWidget txTimeContainer; @UiField ValueViewer txTimeViewer; // Input/output containers @UiField FlowPanel inputContainer; @UiField FlowPanel outputContainer; // Misc info @UiField ValueViewer txVersionViewer; @UiField ValueViewer txLockTimeViewer; // Raw hex @UiField TransactionHexViewer txHexViewer; @UiField FlowPanel coinbaseInputContainer; @UiField ValueViewer coinbaseInputViewer; private final BitcoinPlaceRouter router; private LazyProgressListener progressListener; @Inject public TransactionViewImpl(final BitcoinPlaceRouter router) { this.router = router; txBlockViewer = new BlockViewer(router); initWidget(UI_BINDER.createAndBindUi(this)); } @Override public void setTransaction(final Transaction transaction, final boolean transactionHasErrors) { errorView.setVisible(transactionHasErrors); fullTransactionInformation.setVisible(true); if (transactionHasErrors) { setErrorText(M.messages().transactionPlaceParseError()); } txIdViewer.setHash(transaction.getTransactionId()); txVersionViewer.setValue(transaction.getVersion()); txLockTimeViewer.setValue(transaction.getLockTime()); if (transaction.getInputs() != null) { for (final TransactionInput input : transaction.getInputs()) { final TransactionInputWidget inputWidget = new TransactionInputWidget(input, router); inputContainer.add(inputWidget); } } if (transaction.getOutputs() != null) { for (final TransactionOutput output : transaction.getOutputs()) { final TransactionOutputWidget inputWidget = new TransactionOutputWidget(router, output); outputContainer.add(inputWidget); } } // Lastly, encode the transaction (back) to hex and display it. final RawTransactionContainer rawTransaction = new RawTransactionContainer(); try { TransactionEncodeUtil.encodeTransaction(transaction, rawTransaction); } catch (final Throwable e) { // Eat. } txHexViewer.setValue(rawTransaction); // if(transaction.isCoinbase()) { coinbaseInputContainer.setVisible(true); coinbaseInputViewer.setValue(TextConversionUtil.fromASCIIBytes(rawTransaction.find(TransactionPartType.COINBASE_SCRIPT_SIG).getValue())); } else { coinbaseInputContainer.setVisible(false); } } @Override public void setTransactionInformation(final TransactionInformation transactionInformation) { extraInformationContainer.setVisible(transactionInformation != null); if (transactionInformation == null) { notFoundLabel.setVisible(true); } else if(transactionInformation.getState() != null) { txStateViewer.setValue(transactionInformation.getState().name()); if (transactionInformation.getState() == TransactionState.CONFIRMED) { txBlockContainer.setVisible(true); txBlockViewer.setValue(transactionInformation.getBlockHash()); txConfirmationsContainer.setVisible(true); txConfirmationsViewer.setValue(transactionInformation.getConfirmations()); txTimeContainer.setVisible(true); txTimeViewer.setValue(FormatUtil.formatDateTime(transactionInformation.getTime())); } else { txTimeContainer.setVisible(false); txConfirmationsContainer.setVisible(false); txBlockContainer.setVisible(false); } } progressListener.progressComplete(); } @Override public void setError(final String hash, final Throwable caught) { txIdViewer.setHash(Hex.decode(hash)); setErrorText(M.messages().transactionPlaceBlockchainExistenceNotFound()); fullTransactionInformation.setVisible(false); progressListener.progressComplete(); } private void setErrorText(final String text) { errorView.setVisible(true); transactionFullBlownErrorLabel.setText(text); } @Override public void subscribeProgressListener(final LazyProgressListener listener) { this.progressListener = listener; } }