diff --git a/frontend/src/app/components/tracker/tracker-bar.component.html b/frontend/src/app/components/tracker/tracker-bar.component.html new file mode 100644 index 000000000..c777717b0 --- /dev/null +++ b/frontend/src/app/components/tracker/tracker-bar.component.html @@ -0,0 +1,11 @@ +
\ No newline at end of file diff --git a/frontend/src/app/components/tracker/tracker-bar.component.scss b/frontend/src/app/components/tracker/tracker-bar.component.scss new file mode 100644 index 000000000..4607f9609 --- /dev/null +++ b/frontend/src/app/components/tracker/tracker-bar.component.scss @@ -0,0 +1,136 @@ +.tracker-bar { + width: 100%; + display: flex; + flex-direction: row; + + --div-left-color: var(--box-bg); + --div-right-color: var(--box-bg); + --stage-color: var(--box-bg); + + font-size: clamp(5px, 2.5vw, 15px); + height: clamp(15px, 7.5vw, 45px); + + .stage { + overflow: hidden; + border-top: solid 2px var(--stat-box-bg); + border-bottom: solid 2px var(--stat-box-bg); + background: var(--stage-color); + color: var(--transparent-fg); + padding: 1em; + flex-grow: 1; + flex-shrink: 1; + overflow: hidden; + text-wrap: nowrap; + text-overflow: hidden; + white-space: no-break; + display: flex; + align-items: center; + justify-content: center; + + &:first-child { + border-left: solid 2px var(--stat-box-bg); + border-top-left-radius: 1.6em; + border-bottom-left-radius: 1.6em; + padding-left: 1.6em; + } + &:last-child { + border-right: solid 2px var(--stat-box-bg); + border-top-right-radius: 1.6em; + border-bottom-right-radius: 1.6em; + } + &:nth-child(4n + 3) { + --stage-color: var(--secondary); + } + &.done { + --stage-color: var(--primary); + color: white; + } + &.current { + --stage-color: var(--tertiary); + color: white; + } + &.next { + animation: 1s linear alternate infinite pulse-next; + } + } + + .divider { + position: relative; + overflow: hidden; + flex-shrink: 0; + flex-grow: 0; + background: var(--stat-box-bg); + border-top: solid 2px var(--stat-box-bg); + border-bottom: solid 2px var(--stat-box-bg); + + &.left-done { + --div-left-color: var(--primary); + } + &.left-current { + --div-left-color: var(--tertiary); + } + &.left-blank, &.left-next { + &:nth-child(4n + 0) { + --div-left-color: var(--secondary); + } + } + &.left-next { + animation: 1s linear alternate infinite pulse-next-top; + } + &.right-done { + --div-right-color: var(--primary); + } + &.right-current { + --div-right-color: var(--tertiary); + } + &.right-blank, &.right-next { + &:nth-child(4n + 2) { + --div-right-color: var(--secondary); + } + } + &.right-next { + animation: 1s linear alternate infinite pulse-next-bottom; + } + + &::after, &::before { + content: ''; + width: 100%; + height: 100%; + display: block; + position: absolute; + transform: skew(160deg) translate(58%); + background: var(--div-right-color); + } + &::before { + transform: skew(160deg) translate(-58%); + background: var(--div-left-color); + } + + width: clamp(5px, 2.5vw, 15px); + } + + &.transitions { + .stage, .divider, .divider::before, .divider::after { + transition: color 500ms, border-color 500ms, background-color 500ms; + } + } +} + +@keyframes pulse-next { + to { + border-color: var(--tertiary); + text-shadow: 0 0 0.8em var(--tertiary); + } +} + +@keyframes pulse-next-top { + to { + border-top-color: var(--tertiary); + } +} + +@keyframes pulse-next-bottom { + to { + border-bottom-color: var(--tertiary); + } +} \ No newline at end of file diff --git a/frontend/src/app/components/tracker/tracker-bar.component.ts b/frontend/src/app/components/tracker/tracker-bar.component.ts new file mode 100644 index 000000000..26f2e705b --- /dev/null +++ b/frontend/src/app/components/tracker/tracker-bar.component.ts @@ -0,0 +1,72 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; + +export type TrackerStage = 'waiting' | 'pending' | 'soon' | 'next' | 'confirmed'; + +@Component({ + selector: 'app-tracker-bar', + templateUrl: './tracker-bar.component.html', + styleUrls: ['./tracker-bar.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class TrackerBarComponent implements OnInit, OnChanges { + @Input() stage: TrackerStage = 'waiting'; + + transitionsEnabled: boolean = false; + + stages = { + waiting: { + state: 'blank', + }, + pending: { + state: 'blank', + }, + soon: { + state: 'blank', + }, + next: { + state: 'blank', + }, + confirmed: { + state: 'blank', + }, + }; + stageOrder: TrackerStage[] = ['waiting', 'pending', 'soon', 'next', 'confirmed']; + + constructor ( + private cd: ChangeDetectorRef, + ) {} + + ngOnInit(): void { + this.setStage(); + setTimeout(() => { + this.transitionsEnabled = true; + }, 100) + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.stage) { + this.setStage(); + } + } + + setStage() { + let matched = 0; + for (let stage of this.stageOrder) { + if (stage === this.stage) { + this.stages[stage].state = 'current'; + matched = 1; + } else { + if (matched > 1) { + this.stages[stage].state = 'blank'; + } else if (matched) { + this.stages[stage].state = 'next'; + matched++; + } else { + this.stages[stage].state = 'done'; + } + } + } + this.stages = this.stages; + this.cd.markForCheck(); + } +} \ No newline at end of file diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index 2a47077ca..b7df93e49 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -51,6 +51,7 @@ import { BlockOverviewTooltipComponent } from '../components/block-overview-tool import { BlockFiltersComponent } from '../components/block-filters/block-filters.component'; import { AddressGroupComponent } from '../components/address-group/address-group.component'; import { TrackerComponent } from '../components/tracker/tracker.component'; +import { TrackerBarComponent } from '../components/tracker/tracker-bar.component'; import { SearchFormComponent } from '../components/search-form/search-form.component'; import { AddressLabelsComponent } from '../components/address-labels/address-labels.component'; import { FooterComponent } from '../components/footer/footer.component'; @@ -158,6 +159,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir TransactionsListComponent, AddressGroupComponent, TrackerComponent, + TrackerBarComponent, SearchFormComponent, AddressLabelsComponent, FooterComponent, @@ -292,6 +294,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir TransactionsListComponent, AddressGroupComponent, TrackerComponent, + TrackerBarComponent, SearchFormComponent, AddressLabelsComponent, FooterComponent,