Dynamically resize blockchain to fit container
This commit is contained in:
parent
c8100712e8
commit
975ba653a2
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, Output, EventEmitter, HostListener, ChangeDetectorRef } from '@angular/core';
|
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, Output, EventEmitter, HostListener, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';
|
||||||
import { firstValueFrom, Subscription } from 'rxjs';
|
import { firstValueFrom, Subscription } from 'rxjs';
|
||||||
import { StateService } from '../../services/state.service';
|
import { StateService } from '../../services/state.service';
|
||||||
|
|
||||||
@ -8,12 +8,13 @@ import { StateService } from '../../services/state.service';
|
|||||||
styleUrls: ['./blockchain.component.scss'],
|
styleUrls: ['./blockchain.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class BlockchainComponent implements OnInit, OnDestroy {
|
export class BlockchainComponent implements OnInit, OnDestroy, OnChanges {
|
||||||
@Input() pages: any[] = [];
|
@Input() pages: any[] = [];
|
||||||
@Input() pageIndex: number;
|
@Input() pageIndex: number;
|
||||||
@Input() blocksPerPage: number = 8;
|
@Input() blocksPerPage: number = 8;
|
||||||
@Input() minScrollWidth: number = 0;
|
@Input() minScrollWidth: number = 0;
|
||||||
@Input() scrollableMempool: boolean = false;
|
@Input() scrollableMempool: boolean = false;
|
||||||
|
@Input() containerWidth: number;
|
||||||
|
|
||||||
@Output() mempoolOffsetChange: EventEmitter<number> = new EventEmitter();
|
@Output() mempoolOffsetChange: EventEmitter<number> = new EventEmitter();
|
||||||
|
|
||||||
@ -85,19 +86,25 @@ export class BlockchainComponent implements OnInit, OnDestroy {
|
|||||||
this.mempoolOffsetChange.emit(this.mempoolOffset);
|
this.mempoolOffsetChange.emit(this.mempoolOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
if (changes.containerWidth) {
|
||||||
|
this.onResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onResize(): void {
|
onResize(): void {
|
||||||
if (window.innerWidth >= 768) {
|
const width = this.containerWidth || window.innerWidth;
|
||||||
|
if (width >= 768) {
|
||||||
if (this.stateService.isLiquid()) {
|
if (this.stateService.isLiquid()) {
|
||||||
this.dividerOffset = 420;
|
this.dividerOffset = 420;
|
||||||
} else {
|
} else {
|
||||||
this.dividerOffset = window.innerWidth * 0.5;
|
this.dividerOffset = width * 0.5;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.stateService.isLiquid()) {
|
if (this.stateService.isLiquid()) {
|
||||||
this.dividerOffset = window.innerWidth * 0.5;
|
this.dividerOffset = width * 0.5;
|
||||||
} else {
|
} else {
|
||||||
this.dividerOffset = window.innerWidth * 0.95;
|
this.dividerOffset = width * 0.95;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<div *ngIf="countdown > 0" class="warning-label">{{ eventName }} in {{ countdown | number }} block{{ countdown === 1 ? '' : 's' }}!</div>
|
<div *ngIf="countdown > 0" class="warning-label">{{ eventName }} in {{ countdown | number }} block{{ countdown === 1 ? '' : 's' }}!</div>
|
||||||
|
|
||||||
<div class="blockchain-wrapper" [class.time-ltr]="timeLtr" [class.time-rtl]="!timeLtr">
|
<div class="blockchain-wrapper" [class.time-ltr]="timeLtr" [class.time-rtl]="!timeLtr" #blockchainWrapper>
|
||||||
<div id="blockchain-container" [dir]="timeLtr ? 'rtl' : 'ltr'" #blockchainContainer
|
<div id="blockchain-container" [dir]="timeLtr ? 'rtl' : 'ltr'" #blockchainContainer
|
||||||
(mousedown)="onMouseDown($event)"
|
(mousedown)="onMouseDown($event)"
|
||||||
(pointerdown)="onPointerDown($event)"
|
(pointerdown)="onPointerDown($event)"
|
||||||
@ -18,7 +18,15 @@
|
|||||||
(dragstart)="onDragStart($event)"
|
(dragstart)="onDragStart($event)"
|
||||||
(scroll)="onScroll($event)"
|
(scroll)="onScroll($event)"
|
||||||
>
|
>
|
||||||
<app-blockchain [pageIndex]="pageIndex" [pages]="pages" [blocksPerPage]="blocksPerPage" [minScrollWidth]="minScrollWidth" [scrollableMempool]="true" (mempoolOffsetChange)="onMempoolOffsetChange($event)"></app-blockchain>
|
<app-blockchain
|
||||||
|
[containerWidth]="chainWidth"
|
||||||
|
[pageIndex]="pageIndex"
|
||||||
|
[pages]="pages"
|
||||||
|
[blocksPerPage]="blocksPerPage"
|
||||||
|
[minScrollWidth]="minScrollWidth"
|
||||||
|
[scrollableMempool]="true"
|
||||||
|
(mempoolOffsetChange)="onMempoolOffsetChange($event)"
|
||||||
|
></app-blockchain>
|
||||||
</div>
|
</div>
|
||||||
<div class="reset-scroll" [class.hidden]="pageIndex === 0" (click)="resetScroll()">
|
<div class="reset-scroll" [class.hidden]="pageIndex === 0" (click)="resetScroll()">
|
||||||
<fa-icon [icon]="['fas', 'circle-left']" [fixedWidth]="true"></fa-icon>
|
<fa-icon [icon]="['fas', 'circle-left']" [fixedWidth]="true"></fa-icon>
|
||||||
|
@ -28,6 +28,7 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
|
|||||||
lastMark: MarkBlockState;
|
lastMark: MarkBlockState;
|
||||||
markBlockSubscription: Subscription;
|
markBlockSubscription: Subscription;
|
||||||
blockCounterSubscription: Subscription;
|
blockCounterSubscription: Subscription;
|
||||||
|
@ViewChild('blockchainWrapper', { static: true }) blockchainWrapper: ElementRef;
|
||||||
@ViewChild('blockchainContainer') blockchainContainer: ElementRef;
|
@ViewChild('blockchainContainer') blockchainContainer: ElementRef;
|
||||||
resetScrollSubscription: Subscription;
|
resetScrollSubscription: Subscription;
|
||||||
|
|
||||||
@ -49,6 +50,9 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
|
|||||||
velocity: number = 0;
|
velocity: number = 0;
|
||||||
mempoolOffset: number = 0;
|
mempoolOffset: number = 0;
|
||||||
|
|
||||||
|
private resizeObserver: ResizeObserver;
|
||||||
|
chainWidth: number = window.innerWidth;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
) {
|
) {
|
||||||
@ -70,10 +74,10 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
|
|||||||
this.dynamicBlocksAmount = Math.min(this.blockCount, this.stateService.env.KEEP_BLOCKS_AMOUNT, 8);
|
this.dynamicBlocksAmount = Math.min(this.blockCount, this.stateService.env.KEEP_BLOCKS_AMOUNT, 8);
|
||||||
this.firstPageWidth = 40 + (this.blockWidth * this.dynamicBlocksAmount);
|
this.firstPageWidth = 40 + (this.blockWidth * this.dynamicBlocksAmount);
|
||||||
if (this.blockCount <= Math.min(8, this.stateService.env.KEEP_BLOCKS_AMOUNT)) {
|
if (this.blockCount <= Math.min(8, this.stateService.env.KEEP_BLOCKS_AMOUNT)) {
|
||||||
this.onResize();
|
this.onResize(this.chainWidth);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.onResize();
|
this.onResize(this.chainWidth);
|
||||||
this.updatePages();
|
this.updatePages();
|
||||||
this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => {
|
this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => {
|
||||||
this.timeLtr = !!ltr;
|
this.timeLtr = !!ltr;
|
||||||
@ -151,6 +155,16 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
|
|||||||
this.stateService.resetScroll$.next(false);
|
this.stateService.resetScroll$.next(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if ('ResizeObserver' in window && this.blockchainWrapper?.nativeElement) {
|
||||||
|
this.resizeObserver = new ResizeObserver(entries => {
|
||||||
|
const newChainWidth = entries[0].contentRect.width;
|
||||||
|
if (newChainWidth != this.chainWidth) {
|
||||||
|
this.onResize(newChainWidth);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.resizeObserver.observe(this.blockchainWrapper.nativeElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMempoolOffsetChange(offset): void {
|
onMempoolOffsetChange(offset): void {
|
||||||
@ -171,9 +185,9 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
onResize(width): void {
|
||||||
onResize(): void {
|
this.chainWidth = width;
|
||||||
this.isMobile = window.innerWidth <= 767.98;
|
this.isMobile = this.chainWidth <= 767.98;
|
||||||
let firstVisibleBlock;
|
let firstVisibleBlock;
|
||||||
let offset;
|
let offset;
|
||||||
if (this.blockchainContainer?.nativeElement != null) {
|
if (this.blockchainContainer?.nativeElement != null) {
|
||||||
@ -188,7 +202,7 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.blocksPerPage = Math.ceil(window.innerWidth / this.blockWidth);
|
this.blocksPerPage = Math.ceil(this.chainWidth / this.blockWidth);
|
||||||
this.pageWidth = this.blocksPerPage * this.blockWidth;
|
this.pageWidth = this.blocksPerPage * this.blockWidth;
|
||||||
this.minScrollWidth = this.firstPageWidth + (this.pageWidth * 2);
|
this.minScrollWidth = this.firstPageWidth + (this.pageWidth * 2);
|
||||||
|
|
||||||
@ -295,7 +309,7 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
|
|||||||
onScroll(e) {
|
onScroll(e) {
|
||||||
const middlePage = this.pageIndex === 0 ? this.pages[0] : this.pages[1];
|
const middlePage = this.pageIndex === 0 ? this.pages[0] : this.pages[1];
|
||||||
// compensate for css transform
|
// compensate for css transform
|
||||||
const translation = (this.isMobile ? window.innerWidth * 0.95 : window.innerWidth * 0.5);
|
const translation = (this.isMobile ? this.chainWidth * 0.95 : this.chainWidth * 0.5);
|
||||||
const backThreshold = middlePage.offset + (this.pageWidth * 0.5) + translation;
|
const backThreshold = middlePage.offset + (this.pageWidth * 0.5) + translation;
|
||||||
const forwardThreshold = middlePage.offset - (this.pageWidth * 0.5) + translation;
|
const forwardThreshold = middlePage.offset - (this.pageWidth * 0.5) + translation;
|
||||||
const scrollLeft = this.getConvertedScrollOffset();
|
const scrollLeft = this.getConvertedScrollOffset();
|
||||||
@ -414,10 +428,10 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
|
|||||||
|
|
||||||
blockInViewport(height: number): boolean {
|
blockInViewport(height: number): boolean {
|
||||||
const firstHeight = this.pages[0].height;
|
const firstHeight = this.pages[0].height;
|
||||||
const translation = (this.isMobile ? window.innerWidth * 0.95 : window.innerWidth * 0.5);
|
const translation = (this.isMobile ? this.chainWidth * 0.95 : this.chainWidth * 0.5);
|
||||||
const firstX = this.pages[0].offset - this.getConvertedScrollOffset() + translation;
|
const firstX = this.pages[0].offset - this.getConvertedScrollOffset() + translation;
|
||||||
const xPos = firstX + ((firstHeight - height) * 155);
|
const xPos = firstX + ((firstHeight - height) * 155);
|
||||||
return xPos > -55 && xPos < (window.innerWidth - 100);
|
return xPos > -55 && xPos < (this.chainWidth - 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
getConvertedScrollOffset(): number {
|
getConvertedScrollOffset(): number {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user