diff --git a/frontend/src/app/components/transaction/transaction-preview.component.html b/frontend/src/app/components/transaction/transaction-preview.component.html index 991f51948..44be1dcfa 100644 --- a/frontend/src/app/components/transaction/transaction-preview.component.html +++ b/frontend/src/app/components/transaction/transaction-preview.component.html @@ -2,6 +2,9 @@

Transaction

+ + {{txId.slice(0,-4)}}{{txId.slice(-4)}} +
@@ -13,21 +16,24 @@
-

- - {{ txId }} - -

+
+ + Confidential + + + + + ‎{{ (tx.status.confirmed ? tx.status.block_time : transactionTime) * 1000 | date:'yyyy-MM-dd HH:mm' }} + Fee {{ tx.fee | number }} sat +
- +
-

- Confidential - - - +

+ +

{{ tx.feePerVsize | feeRounding }} sat/vB diff --git a/frontend/src/app/components/transaction/transaction-preview.component.scss b/frontend/src/app/components/transaction/transaction-preview.component.scss index 4a65dd0d8..7aefe0063 100644 --- a/frontend/src/app/components/transaction/transaction-preview.component.scss +++ b/frontend/src/app/components/transaction/transaction-preview.component.scss @@ -10,26 +10,10 @@ font-size: 28px; } -.btn-small-height { - line-height: 1.1; -} - -.arrow-green { - color: #1a9436; -} - -.arrow-red { - color: #dc3545; -} - .row { flex-direction: row; } -.effective-fee-container { - display: inline-block; -} - .title { h2 { line-height: 1; @@ -46,8 +30,9 @@ display: flex; flex-direction: row; justify-content: space-between; - align-items: center; - margin-bottom: 10px; + align-items: baseline; + margin-bottom: 2px; + max-width: 100%; h1 { font-size: 52px; @@ -58,6 +43,43 @@ .features { font-size: 24px; } + + & > * { + flex-grow: 0; + flex-shrink: 0; + } + + .tx-link { + flex-grow: 1; + flex-shrink: 1; + margin: 0 1em; + overflow: hidden; + white-space: nowrap; + display: flex; + flex-direction: row; + align-items: baseline; + + .truncated { + flex-grow: 1; + flex-shrink: 1; + overflow: hidden; + text-overflow: ellipsis; + margin-right: -2px; + } + + .last-four { + flex-shrink: 0; + flex-grow: 0; + } + } + + .features { + align-self: center; + } +} + +.top-data { + font-size: 28px; } .table { @@ -68,6 +90,23 @@ } } +.field { + font-size: 32px; + margin: 0; + + ::ng-deep .symbol { + font-size: 24px; + } + + .label { + color: #ffffff66; + } + + &.pair > *:first-child { + margin-right: 1em; + } +} + .tx-link { display: inline; font-size: 28px; @@ -87,15 +126,6 @@ right: 0; margin: auto; text-align: center; - - .field { - font-size: 32px; - margin: 0; - - ::ng-deep .symbol { - font-size: 24px; - } - } } .overlaid { diff --git a/frontend/src/app/components/transaction/transaction-preview.component.ts b/frontend/src/app/components/transaction/transaction-preview.component.ts index 15a881446..d30789f6b 100644 --- a/frontend/src/app/components/transaction/transaction-preview.component.ts +++ b/frontend/src/app/components/transaction/transaction-preview.component.ts @@ -29,6 +29,7 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy { isLoadingTx = true; error: any = undefined; errorUnblinded: any = undefined; + transactionTime = -1; subscription: Subscription; fetchCpfpSubscription: Subscription; cpfpInfo: CpfpInfo | null; @@ -163,6 +164,12 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy { this.opReturns = this.getOpReturns(this.tx); this.extraData = this.chooseExtraData(); + if (!tx.status.confirmed && tx.firstSeen) { + this.transactionTime = tx.firstSeen; + } else { + this.getTransactionTime(); + } + if (!this.tx.status.confirmed) { if (tx.cpfpChecked) { this.cpfpInfo = { @@ -185,10 +192,26 @@ export class TransactionPreviewComponent implements OnInit, OnDestroy { ); } + getTransactionTime() { + this.openGraphService.waitFor('tx-time'); + this.apiService + .getTransactionTimes$([this.tx.txid]) + .pipe( + catchError((err) => { + return of(0); + }) + ) + .subscribe((transactionTimes) => { + this.transactionTime = transactionTimes[0]; + this.openGraphService.waitOver('tx-time'); + }); + } + resetTransaction() { this.error = undefined; this.tx = null; this.isLoadingTx = true; + this.transactionTime = -1; this.cpfpInfo = null; this.showCpfpDetails = false; } diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html index d3452b5a9..c4771c58c 100644 --- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html +++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.html @@ -5,14 +5,14 @@ markerUnits="strokeWidth" markerWidth="1.5" markerHeight="1" orient="auto"> - + - + + + + + + + + + - - + + diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss index ea45e4495..6de41b95f 100644 --- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss +++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.scss @@ -1,6 +1,15 @@ .bowtie { .line { - stroke: white; fill: none; + + &.input { + stroke: url(#input-gradient); + } + &.output { + stroke: url(#output-gradient); + } + &.fee { + stroke: url(#fee-gradient); + } } } diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts index 68fdabeae..427a282a9 100644 --- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts +++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts @@ -14,7 +14,7 @@ interface SvgLine { }) export class TxBowtieGraphComponent implements OnInit, OnChanges { @Input() tx: Transaction; - @Input() isLiquid: boolean = false; + @Input() network: string; @Input() width = 1200; @Input() height = 600; @Input() combinedWeight = 100; @@ -24,12 +24,32 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { inputs: SvgLine[]; outputs: SvgLine[]; middle: SvgLine; + isLiquid: boolean = false; + + gradientColors = { + '': ['#9339f4', '#105fb0'], + bisq: ['#9339f4', '#105fb0'], + // liquid: ['#116761', '#183550'], + liquid: ['#09a197', '#0f62af'], + // 'liquidtestnet': ['#494a4a', '#272e46'], + 'liquidtestnet': ['#d2d2d2', '#979797'], + // testnet: ['#1d486f', '#183550'], + testnet: ['#4edf77', '#10a0af'], + // signet: ['#6f1d5d', '#471850'], + signet: ['#d24fc8', '#a84fd2'], + }; + + gradient: string[] = ['#105fb0', '#105fb0']; ngOnInit(): void { + this.isLiquid = (this.network === 'liquid' || this.network === 'liquidtestnet'); + this.gradient = this.gradientColors[this.network]; this.initGraph(); } ngOnChanges(): void { + this.isLiquid = (this.network === 'liquid' || this.network === 'liquidtestnet'); + this.gradient = this.gradientColors[this.network]; this.initGraph(); } @@ -46,7 +66,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { this.middle = { path: `M ${(this.width / 2) - 50} ${(this.height / 2) + 0.5} L ${(this.width / 2) + 50} ${(this.height / 2) + 0.5}`, - style: `stroke-width: ${this.combinedWeight + 0.5}` + style: `stroke-width: ${this.combinedWeight + 0.5}; stroke: ${this.gradient[1]}` }; } @@ -132,6 +152,10 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { const start = side === 'in' ? (weight * 0.5) : this.width - (weight * 0.5); const center = this.width / 2 + (side === 'in' ? -45 : 45 ); const midpoint = (start + center) / 2; + // correct for svg horizontal gradient bug + if (Math.round(outer) === Math.round(inner)) { + outer -= 1; + } return `M ${start} ${outer} C ${midpoint} ${outer}, ${midpoint} ${inner}, ${center} ${inner}`; }