mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
transaction view pagination complete
This commit is contained in:
parent
6b12888111
commit
7f03778ec7
3 changed files with 125 additions and 27 deletions
|
@ -934,7 +934,9 @@ public class ElectrumServer {
|
||||||
|
|
||||||
Set<BlockTransactionHash> setReferences = new HashSet<>();
|
Set<BlockTransactionHash> setReferences = new HashSet<>();
|
||||||
for(Set<BlockTransactionHash> outputReferences : outputTransactionReferences) {
|
for(Set<BlockTransactionHash> outputReferences : outputTransactionReferences) {
|
||||||
setReferences.addAll(outputReferences);
|
if(outputReferences != null) {
|
||||||
|
setReferences.addAll(outputReferences);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setReferences.remove(null);
|
setReferences.remove(null);
|
||||||
setReferences.remove(UNFETCHABLE_BLOCK_TRANSACTION);
|
setReferences.remove(UNFETCHABLE_BLOCK_TRANSACTION);
|
||||||
|
@ -952,15 +954,17 @@ public class ElectrumServer {
|
||||||
|
|
||||||
for(int i = 0; i < outputTransactionReferences.size(); i++) {
|
for(int i = 0; i < outputTransactionReferences.size(); i++) {
|
||||||
Set<BlockTransactionHash> outputReferences = outputTransactionReferences.get(i);
|
Set<BlockTransactionHash> outputReferences = outputTransactionReferences.get(i);
|
||||||
for(BlockTransactionHash reference : outputReferences) {
|
if(outputReferences != null) {
|
||||||
if(reference == UNFETCHABLE_BLOCK_TRANSACTION) {
|
for(BlockTransactionHash reference : outputReferences) {
|
||||||
blockTransactions.set(i, UNFETCHABLE_BLOCK_TRANSACTION);
|
if(reference == UNFETCHABLE_BLOCK_TRANSACTION) {
|
||||||
} else {
|
blockTransactions.set(i, UNFETCHABLE_BLOCK_TRANSACTION);
|
||||||
BlockTransaction blockTransaction = transactionMap.get(reference.getHash());
|
} else {
|
||||||
for(TransactionInput input : blockTransaction.getTransaction().getInputs()) {
|
BlockTransaction blockTransaction = transactionMap.get(reference.getHash());
|
||||||
if(input.getOutpoint().getHash().equals(transaction.getTxId()) && input.getOutpoint().getIndex() == i) {
|
for(TransactionInput input : blockTransaction.getTransaction().getInputs()) {
|
||||||
if(blockTransactions.set(i, blockTransaction) != null) {
|
if(input.getOutpoint().getHash().equals(transaction.getTxId()) && input.getOutpoint().getIndex() == i) {
|
||||||
throw new IllegalStateException("Double spend detected for output #" + i + " on hash " + reference.getHash());
|
if(blockTransactions.set(i, blockTransaction) != null) {
|
||||||
|
throw new IllegalStateException("Double spend detected for output #" + i + " on hash " + reference.getHash());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,6 @@ public class PageForm extends IndexedTransactionForm {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Load More...";
|
return "...";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,12 @@ public class TransactionController implements Initializable {
|
||||||
refreshTxHex();
|
refreshTxHex();
|
||||||
fetchThisAndInputBlockTransactions(0, highestInputIndex);
|
fetchThisAndInputBlockTransactions(0, highestInputIndex);
|
||||||
fetchOutputBlockTransactions(0, highestOutputIndex);
|
fetchOutputBlockTransactions(0, highestOutputIndex);
|
||||||
|
|
||||||
|
if(TransactionView.INPUT.equals(initialView) && initialIndex >= PageForm.PAGE_SIZE) {
|
||||||
|
fetchThisAndInputBlockTransactions(initialIndex, initialIndex + 1);
|
||||||
|
} else if(TransactionView.OUTPUT.equals(initialView) && initialIndex >= PageForm.PAGE_SIZE) {
|
||||||
|
fetchOutputBlockTransactions(initialIndex, initialIndex + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeTxTree() {
|
private void initializeTxTree() {
|
||||||
|
@ -83,9 +89,13 @@ public class TransactionController implements Initializable {
|
||||||
inputsItem.setExpanded(true);
|
inputsItem.setExpanded(true);
|
||||||
boolean inputPagingAdded = false;
|
boolean inputPagingAdded = false;
|
||||||
for(int i = 0; i < getTransaction().getInputs().size(); i++) {
|
for(int i = 0; i < getTransaction().getInputs().size(); i++) {
|
||||||
if(i < PageForm.PAGE_SIZE || (TransactionView.INPUT.equals(initialView) && i == initialIndex)) {
|
if(i < PageForm.PAGE_SIZE) {
|
||||||
TreeItem<TransactionForm> inputItem = createInputTreeItem(i);
|
TreeItem<TransactionForm> inputItem = createInputTreeItem(i);
|
||||||
inputsItem.getChildren().add(inputItem);
|
inputsItem.getChildren().add(inputItem);
|
||||||
|
} else if(TransactionView.INPUT.equals(initialView) && i == initialIndex) {
|
||||||
|
TreeItem<TransactionForm> inputItem = createInputTreeItem(i);
|
||||||
|
inputsItem.getChildren().add(inputItem);
|
||||||
|
inputPagingAdded = false;
|
||||||
} else if(!inputPagingAdded) {
|
} else if(!inputPagingAdded) {
|
||||||
PageForm pageForm = new PageForm(TransactionView.INPUT, i, i + PageForm.PAGE_SIZE);
|
PageForm pageForm = new PageForm(TransactionView.INPUT, i, i + PageForm.PAGE_SIZE);
|
||||||
TreeItem<TransactionForm> pageItem = new TreeItem<>(pageForm);
|
TreeItem<TransactionForm> pageItem = new TreeItem<>(pageForm);
|
||||||
|
@ -99,9 +109,13 @@ public class TransactionController implements Initializable {
|
||||||
outputsItem.setExpanded(true);
|
outputsItem.setExpanded(true);
|
||||||
boolean outputPagingAdded = false;
|
boolean outputPagingAdded = false;
|
||||||
for(int i = 0; i < getTransaction().getOutputs().size(); i++) {
|
for(int i = 0; i < getTransaction().getOutputs().size(); i++) {
|
||||||
if(i < PageForm.PAGE_SIZE || (TransactionView.OUTPUT.equals(initialView) && i == initialIndex)) {
|
if(i < PageForm.PAGE_SIZE) {
|
||||||
TreeItem<TransactionForm> outputItem = createOutputTreeItem(i);
|
TreeItem<TransactionForm> outputItem = createOutputTreeItem(i);
|
||||||
outputsItem.getChildren().add(outputItem);
|
outputsItem.getChildren().add(outputItem);
|
||||||
|
} else if(TransactionView.OUTPUT.equals(initialView) && i == initialIndex) {
|
||||||
|
TreeItem<TransactionForm> outputItem = createOutputTreeItem(i);
|
||||||
|
outputsItem.getChildren().add(outputItem);
|
||||||
|
outputPagingAdded = false;
|
||||||
} else if(!outputPagingAdded) {
|
} else if(!outputPagingAdded) {
|
||||||
PageForm pageForm = new PageForm(TransactionView.OUTPUT, i, i + PageForm.PAGE_SIZE);
|
PageForm pageForm = new PageForm(TransactionView.OUTPUT, i, i + PageForm.PAGE_SIZE);
|
||||||
TreeItem<TransactionForm> pageItem = new TreeItem<>(pageForm);
|
TreeItem<TransactionForm> pageItem = new TreeItem<>(pageForm);
|
||||||
|
@ -135,18 +149,40 @@ public class TransactionController implements Initializable {
|
||||||
|
|
||||||
if(optParentItem.isPresent()) {
|
if(optParentItem.isPresent()) {
|
||||||
TreeItem<TransactionForm> parentItem = optParentItem.get();
|
TreeItem<TransactionForm> parentItem = optParentItem.get();
|
||||||
|
int treeIndex = parentItem.getChildren().indexOf(selectedItem);
|
||||||
parentItem.getChildren().remove(selectedItem);
|
parentItem.getChildren().remove(selectedItem);
|
||||||
|
|
||||||
int max = pageForm.getView().equals(TransactionView.INPUT) ? getTransaction().getInputs().size() : getTransaction().getOutputs().size();
|
int max = pageForm.getView().equals(TransactionView.INPUT) ? getTransaction().getInputs().size() : getTransaction().getOutputs().size();
|
||||||
for(int i = pageForm.getPageStart(); i < max && i < pageForm.getPageEnd(); i++) {
|
for(int i = pageForm.getPageStart(); i < max && i < pageForm.getPageEnd(); i++) {
|
||||||
TreeItem<TransactionForm> newItem = pageForm.getView().equals(TransactionView.INPUT) ? createInputTreeItem(i) : createOutputTreeItem(i);
|
int txIndex = i;
|
||||||
parentItem.getChildren().add(newItem);
|
TreeItem<TransactionForm> newItem = pageForm.getView().equals(TransactionView.INPUT) ? createInputTreeItem(txIndex) : createOutputTreeItem(txIndex);
|
||||||
|
Optional<TreeItem<TransactionForm>> optionalExisting = parentItem.getChildren().stream().filter(item -> ((IndexedTransactionForm)item.getValue()).getIndex() == txIndex).findFirst();
|
||||||
|
|
||||||
|
boolean pageItem = false;
|
||||||
|
if(optionalExisting.isPresent() && optionalExisting.get().getValue() instanceof PageForm) {
|
||||||
|
parentItem.getChildren().remove(optionalExisting.get());
|
||||||
|
pageItem = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(optionalExisting.isEmpty() || pageItem) {
|
||||||
|
if(treeIndex >= parentItem.getChildren().size()) {
|
||||||
|
parentItem.getChildren().add(newItem);
|
||||||
|
} else {
|
||||||
|
parentItem.getChildren().add(treeIndex, newItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
treeIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pageForm.getPageEnd() < max) {
|
if(pageForm.getPageEnd() < max) {
|
||||||
PageForm nextPageForm = new PageForm(pageForm.getView(), pageForm.getPageStart() + PageForm.PAGE_SIZE, pageForm.getPageEnd() + PageForm.PAGE_SIZE);
|
PageForm nextPageForm = new PageForm(pageForm.getView(), pageForm.getPageStart() + PageForm.PAGE_SIZE, pageForm.getPageEnd() + PageForm.PAGE_SIZE);
|
||||||
TreeItem<TransactionForm> nextPageItem = new TreeItem<>(nextPageForm);
|
TreeItem<TransactionForm> nextPageItem = new TreeItem<>(nextPageForm);
|
||||||
parentItem.getChildren().add(nextPageItem);
|
if(pageForm.getPageEnd() >= parentItem.getChildren().size()) {
|
||||||
|
parentItem.getChildren().add(nextPageItem);
|
||||||
|
} else {
|
||||||
|
parentItem.getChildren().add(pageForm.getPageEnd(), nextPageItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pageForm.getView().equals(TransactionView.INPUT)) {
|
if(pageForm.getView().equals(TransactionView.INPUT)) {
|
||||||
|
@ -158,10 +194,7 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
setTreeSelection(pageForm.getView(), pageForm.getPageStart());
|
setTreeSelection(pageForm.getView(), pageForm.getPageStart());
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(this::refreshTxHex);
|
||||||
txtree.scrollTo(pageForm.getPageStart());
|
|
||||||
refreshTxHex();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -220,26 +253,35 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTreeSelection(TransactionView view, Integer index) {
|
public void setTreeSelection(TransactionView view, Integer index) {
|
||||||
select(txtree.getRoot(), view, index);
|
TreeItem<TransactionForm> treeItem = getTreeItem(view, index);
|
||||||
|
txtree.getSelectionModel().select(treeItem);
|
||||||
|
txtree.scrollTo(txtree.getRow(treeItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void select(TreeItem<TransactionForm> treeItem, TransactionView view, Integer index) {
|
private TreeItem<TransactionForm> getTreeItem(TransactionView view, Integer index) {
|
||||||
|
return getTreeItem(txtree.getRoot(), view, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeItem<TransactionForm> getTreeItem(TreeItem<TransactionForm> treeItem, TransactionView view, Integer index) {
|
||||||
if(treeItem.getValue().getView().equals(view)) {
|
if(treeItem.getValue().getView().equals(view)) {
|
||||||
if(view.equals(TransactionView.INPUT) || view.equals(TransactionView.OUTPUT)) {
|
if(view.equals(TransactionView.INPUT) || view.equals(TransactionView.OUTPUT)) {
|
||||||
IndexedTransactionForm txForm = (IndexedTransactionForm)treeItem.getValue();
|
IndexedTransactionForm txForm = (IndexedTransactionForm)treeItem.getValue();
|
||||||
if(txForm.getIndex() == index) {
|
if(txForm.getIndex() == index) {
|
||||||
txtree.getSelectionModel().select(treeItem);
|
return treeItem;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
txtree.getSelectionModel().select(treeItem);
|
return treeItem;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
for(TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
||||||
select(childItem, view, index);
|
TreeItem<TransactionForm> foundItem = getTreeItem(childItem, view, index);
|
||||||
|
if(foundItem != null) {
|
||||||
|
return foundItem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshTxHex() {
|
void refreshTxHex() {
|
||||||
|
@ -452,6 +494,58 @@ public class TransactionController implements Initializable {
|
||||||
this.initialIndex = initialIndex;
|
this.initialIndex = initialIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void viewTransaction(ViewTransactionEvent event) {
|
||||||
|
if(txdata.getTransaction().getTxId().equals(event.getBlockTransaction().getTransaction().getTxId())) {
|
||||||
|
TreeItem<TransactionForm> existingItem = getTreeItem(event.getInitialView(), event.getInitialIndex());
|
||||||
|
if(existingItem != null && !(existingItem.getValue() instanceof PageForm)) {
|
||||||
|
setTreeSelection(event.getInitialView(), event.getInitialIndex());
|
||||||
|
} else if(event.getInitialView().equals(TransactionView.INPUT) || event.getInitialView().equals(TransactionView.OUTPUT)) {
|
||||||
|
TreeItem<TransactionForm> parentItem = getTreeItem(event.getInitialView().equals(TransactionView.INPUT) ? TransactionView.INPUTS : TransactionView.OUTPUTS, null);
|
||||||
|
|
||||||
|
TreeItem<TransactionForm> newItem = event.getInitialView().equals(TransactionView.INPUT) ? createInputTreeItem(event.getInitialIndex()) : createOutputTreeItem(event.getInitialIndex());
|
||||||
|
PageForm nextPageForm = new PageForm(event.getInitialView(), event.getInitialIndex() + 1, event.getInitialIndex() + 1 + PageForm.PAGE_SIZE);
|
||||||
|
TreeItem<TransactionForm> nextPageItem = new TreeItem<>(nextPageForm);
|
||||||
|
|
||||||
|
if(existingItem != null) {
|
||||||
|
parentItem.getChildren().remove(existingItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
int max = event.getInitialView().equals(TransactionView.INPUT) ? getTransaction().getInputs().size() : getTransaction().getOutputs().size();
|
||||||
|
int highestIndex = ((IndexedTransactionForm)parentItem.getChildren().get(parentItem.getChildren().size() - 1).getValue()).getIndex();
|
||||||
|
if(event.getInitialIndex() < highestIndex) {
|
||||||
|
for(int i = 0; i < parentItem.getChildren().size(); i++) {
|
||||||
|
TreeItem<TransactionForm> childItem = parentItem.getChildren().get(i);
|
||||||
|
IndexedTransactionForm txForm = (IndexedTransactionForm)childItem.getValue();
|
||||||
|
if(txForm.getIndex() > event.getInitialIndex()) {
|
||||||
|
parentItem.getChildren().add(i, newItem);
|
||||||
|
if(txForm.getIndex() != event.getInitialIndex() + 1) {
|
||||||
|
parentItem.getChildren().add(i + 1, nextPageItem);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parentItem.getChildren().add(newItem);
|
||||||
|
if((event.getInitialIndex() + 1) != max) {
|
||||||
|
parentItem.getChildren().add(nextPageItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(event.getInitialView().equals(TransactionView.INPUT)) {
|
||||||
|
highestInputIndex = Math.min(max, event.getInitialIndex());
|
||||||
|
fetchThisAndInputBlockTransactions(event.getInitialIndex(), event.getInitialIndex() + 1);
|
||||||
|
} else {
|
||||||
|
highestOutputIndex = Math.min(max, event.getInitialIndex());
|
||||||
|
fetchOutputBlockTransactions(event.getInitialIndex(), event.getInitialIndex() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTreeSelection(event.getInitialView(), event.getInitialIndex());
|
||||||
|
Platform.runLater(this::refreshTxHex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void transactionChanged(TransactionChangedEvent event) {
|
public void transactionChanged(TransactionChangedEvent event) {
|
||||||
if(event.getTransaction().equals(getTransaction())) {
|
if(event.getTransaction().equals(getTransaction())) {
|
||||||
|
|
Loading…
Reference in a new issue