Allow smooth key navigation in block table and pegs table
This commit is contained in:
parent
524619f48e
commit
5deb8c3149
@ -594,19 +594,6 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
this.transactionsError = null;
|
this.transactionsError = null;
|
||||||
target.scrollIntoView(); // works for chrome
|
target.scrollIntoView(); // works for chrome
|
||||||
this.router.navigate([], { queryParams: { page: page }, queryParamsHandling: 'merge' });
|
this.router.navigate([], { queryParams: { page: page }, queryParamsHandling: 'merge' });
|
||||||
|
|
||||||
this.electrsApiService.getBlockTransactions$(this.block.id, start)
|
|
||||||
.pipe(
|
|
||||||
catchError((err) => {
|
|
||||||
this.transactionsError = err;
|
|
||||||
return of([]);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.subscribe((transactions) => {
|
|
||||||
this.transactions = transactions;
|
|
||||||
this.isLoadingTransactions = false;
|
|
||||||
target.scrollIntoView(); // works for firefox
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleShowDetails() {
|
toggleShowDetails() {
|
||||||
|
@ -26,6 +26,11 @@ export class BlocksList implements OnInit {
|
|||||||
auditAvailable = false;
|
auditAvailable = false;
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
fromBlockHeight = undefined;
|
fromBlockHeight = undefined;
|
||||||
|
lastKeyNavTime = 0;
|
||||||
|
lastBlockHeightFetched = -1;
|
||||||
|
isArrowKeyPressed = false;
|
||||||
|
keydownListener: EventListener;
|
||||||
|
keyupListener: EventListener;
|
||||||
paginationMaxSize: number;
|
paginationMaxSize: number;
|
||||||
page = 1;
|
page = 1;
|
||||||
lastPage = 1;
|
lastPage = 1;
|
||||||
@ -54,6 +59,10 @@ export class BlocksList implements OnInit {
|
|||||||
if (this.locale.startsWith('ar') || this.locale.startsWith('fa') || this.locale.startsWith('he')) {
|
if (this.locale.startsWith('ar') || this.locale.startsWith('fa') || this.locale.startsWith('he')) {
|
||||||
this.dir = 'rtl';
|
this.dir = 'rtl';
|
||||||
}
|
}
|
||||||
|
this.keydownListener = this.onKeyDown.bind(this);
|
||||||
|
this.keyupListener = this.onKeyUp.bind(this);
|
||||||
|
window.addEventListener('keydown', this.keydownListener);
|
||||||
|
window.addEventListener('keyup', this.keyupListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -63,14 +72,12 @@ export class BlocksList implements OnInit {
|
|||||||
|
|
||||||
if (!this.widget) {
|
if (!this.widget) {
|
||||||
this.websocketService.want(['blocks']);
|
this.websocketService.want(['blocks']);
|
||||||
this.blocksCountInitializedSubscription = this.blocksCountInitialized$.pipe(
|
this.blocksCountInitializedSubscription = combineLatest([this.blocksCountInitialized$, this.route.queryParams]).pipe(
|
||||||
filter(blocksCountInitialized => blocksCountInitialized),
|
filter(([blocksCountInitialized, _]) => blocksCountInitialized),
|
||||||
take(1),
|
tap(([_, params]) => {
|
||||||
switchMap(() => this.route.queryParams),
|
|
||||||
take(1),
|
|
||||||
tap(params => {
|
|
||||||
this.page = +params['page'] || 1;
|
this.page = +params['page'] || 1;
|
||||||
this.pageChange(this.page);
|
this.page === 1 ? this.fromHeightSubject.next(undefined) : this.fromHeightSubject.next((this.blocksCount - 1) - (this.page - 1) * 15);
|
||||||
|
this.cd.markForCheck();
|
||||||
})
|
})
|
||||||
).subscribe();
|
).subscribe();
|
||||||
|
|
||||||
@ -79,13 +86,16 @@ export class BlocksList implements OnInit {
|
|||||||
const nextKey = this.dir === 'ltr' ? 'ArrowRight' : 'ArrowLeft';
|
const nextKey = this.dir === 'ltr' ? 'ArrowRight' : 'ArrowLeft';
|
||||||
if (event.key === prevKey && this.page > 1) {
|
if (event.key === prevKey && this.page > 1) {
|
||||||
this.page--;
|
this.page--;
|
||||||
this.pageChange(this.page);
|
this.page === 1 ? this.isArrowKeyPressed = false : null;
|
||||||
|
this.keyNavPageChange(this.page);
|
||||||
|
this.lastKeyNavTime = Date.now();
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
|
|
||||||
}
|
}
|
||||||
if (event.key === nextKey && this.page * 15 < this.blocksCount) {
|
if (event.key === nextKey && this.page * 15 < this.blocksCount) {
|
||||||
this.page++;
|
this.page++;
|
||||||
this.pageChange(this.page);
|
this.page >= this.blocksCount / 15 ? this.isArrowKeyPressed = false : null;
|
||||||
|
this.keyNavPageChange(this.page);
|
||||||
|
this.lastKeyNavTime = Date.now();
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -107,8 +117,10 @@ export class BlocksList implements OnInit {
|
|||||||
|
|
||||||
this.blocks$ = combineLatest([
|
this.blocks$ = combineLatest([
|
||||||
this.fromHeightSubject.pipe(
|
this.fromHeightSubject.pipe(
|
||||||
|
filter(fromBlockHeight => fromBlockHeight !== this.lastBlockHeightFetched),
|
||||||
switchMap((fromBlockHeight) => {
|
switchMap((fromBlockHeight) => {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
this.lastBlockHeightFetched = fromBlockHeight;
|
||||||
return this.apiService.getBlocks$(this.page === 1 ? undefined : fromBlockHeight)
|
return this.apiService.getBlocks$(this.page === 1 ? undefined : fromBlockHeight)
|
||||||
.pipe(
|
.pipe(
|
||||||
tap(blocks => {
|
tap(blocks => {
|
||||||
@ -177,7 +189,32 @@ export class BlocksList implements OnInit {
|
|||||||
|
|
||||||
pageChange(page: number): void {
|
pageChange(page: number): void {
|
||||||
this.router.navigate([], { queryParams: { page: page } });
|
this.router.navigate([], { queryParams: { page: page } });
|
||||||
this.fromHeightSubject.next((this.blocksCount - 1) - (page - 1) * 15);
|
}
|
||||||
|
|
||||||
|
keyNavPageChange(page: number): void {
|
||||||
|
this.isLoading = true;
|
||||||
|
if (this.isArrowKeyPressed) {
|
||||||
|
timer(400).pipe(
|
||||||
|
take(1),
|
||||||
|
filter(() => Date.now() - this.lastKeyNavTime >= 400 && this.isArrowKeyPressed === false),
|
||||||
|
).subscribe(() => {
|
||||||
|
this.pageChange(page);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.pageChange(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyDown(event: KeyboardEvent) {
|
||||||
|
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||||
|
this.isArrowKeyPressed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyUp(event: KeyboardEvent) {
|
||||||
|
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||||
|
this.isArrowKeyPressed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trackByBlock(index: number, block: BlockExtended): number {
|
trackByBlock(index: number, block: BlockExtended): number {
|
||||||
@ -191,5 +228,7 @@ export class BlocksList implements OnInit {
|
|||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.blocksCountInitializedSubscription?.unsubscribe();
|
this.blocksCountInitializedSubscription?.unsubscribe();
|
||||||
this.keyNavigationSubscription?.unsubscribe();
|
this.keyNavigationSubscription?.unsubscribe();
|
||||||
|
window.removeEventListener('keydown', this.keydownListener);
|
||||||
|
window.removeEventListener('keyup', this.keyupListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,10 @@ export class RecentPegsListComponent implements OnInit {
|
|||||||
queryParamSubscription: Subscription;
|
queryParamSubscription: Subscription;
|
||||||
keyNavigationSubscription: Subscription;
|
keyNavigationSubscription: Subscription;
|
||||||
dir: 'rtl' | 'ltr' = 'ltr';
|
dir: 'rtl' | 'ltr' = 'ltr';
|
||||||
|
lastKeyNavTime = 0;
|
||||||
|
isArrowKeyPressed = false;
|
||||||
|
keydownListener: EventListener;
|
||||||
|
keyupListener: EventListener;
|
||||||
|
|
||||||
private destroy$ = new Subject();
|
private destroy$ = new Subject();
|
||||||
|
|
||||||
@ -55,6 +59,10 @@ export class RecentPegsListComponent implements OnInit {
|
|||||||
if (this.locale.startsWith('ar') || this.locale.startsWith('fa') || this.locale.startsWith('he')) {
|
if (this.locale.startsWith('ar') || this.locale.startsWith('fa') || this.locale.startsWith('he')) {
|
||||||
this.dir = 'rtl';
|
this.dir = 'rtl';
|
||||||
}
|
}
|
||||||
|
this.keydownListener = this.onKeyDown.bind(this);
|
||||||
|
this.keyupListener = this.onKeyUp.bind(this);
|
||||||
|
window.addEventListener('keydown', this.keydownListener);
|
||||||
|
window.addEventListener('keyup', this.keyupListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -67,7 +75,10 @@ export class RecentPegsListComponent implements OnInit {
|
|||||||
this.websocketService.want(['blocks']);
|
this.websocketService.want(['blocks']);
|
||||||
|
|
||||||
this.queryParamSubscription = this.route.queryParams.pipe(
|
this.queryParamSubscription = this.route.queryParams.pipe(
|
||||||
tap((params) => this.pageChange(+params['page'] || 1)),
|
tap((params) => {
|
||||||
|
this.page = +params['page'] || 1;
|
||||||
|
this.startingIndexSubject.next((this.page - 1) * 15);
|
||||||
|
}),
|
||||||
).subscribe();
|
).subscribe();
|
||||||
|
|
||||||
this.keyNavigationSubscription = this.stateService.keyNavigation$.subscribe((event) => {
|
this.keyNavigationSubscription = this.stateService.keyNavigation$.subscribe((event) => {
|
||||||
@ -75,12 +86,16 @@ export class RecentPegsListComponent implements OnInit {
|
|||||||
const nextKey = this.dir === 'ltr' ? 'ArrowRight' : 'ArrowLeft';
|
const nextKey = this.dir === 'ltr' ? 'ArrowRight' : 'ArrowLeft';
|
||||||
if (event.key === prevKey && this.page > 1) {
|
if (event.key === prevKey && this.page > 1) {
|
||||||
this.page--;
|
this.page--;
|
||||||
this.pageChange(this.page);
|
this.page === 1 ? this.isArrowKeyPressed = false : null;
|
||||||
|
this.keyNavPageChange(this.page);
|
||||||
|
this.lastKeyNavTime = Date.now();
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
}
|
}
|
||||||
if (event.key === nextKey && this.page < this.pegsCount / this.pageSize) {
|
if (event.key === nextKey && this.page < this.pegsCount / this.pageSize) {
|
||||||
this.page++;
|
this.page++;
|
||||||
this.pageChange(this.page);
|
this.page >= this.pegsCount / this.pageSize ? this.isArrowKeyPressed = false : null;
|
||||||
|
this.keyNavPageChange(this.page);
|
||||||
|
this.lastKeyNavTime = Date.now();
|
||||||
this.cd.markForCheck();
|
this.cd.markForCheck();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -166,12 +181,39 @@ export class RecentPegsListComponent implements OnInit {
|
|||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
this.queryParamSubscription?.unsubscribe();
|
this.queryParamSubscription?.unsubscribe();
|
||||||
this.keyNavigationSubscription?.unsubscribe();
|
this.keyNavigationSubscription?.unsubscribe();
|
||||||
|
window.removeEventListener('keydown', this.keydownListener);
|
||||||
|
window.removeEventListener('keyup', this.keyupListener);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pageChange(page: number): void {
|
pageChange(page: number): void {
|
||||||
this.router.navigate([], { queryParams: { page: page } });
|
this.router.navigate([], { queryParams: { page: page } });
|
||||||
this.startingIndexSubject.next((page - 1) * 15);
|
}
|
||||||
this.page = page;
|
|
||||||
|
keyNavPageChange(page: number): void {
|
||||||
|
this.isLoading = true;
|
||||||
|
if (this.isArrowKeyPressed) {
|
||||||
|
timer(400).pipe(
|
||||||
|
take(1),
|
||||||
|
filter(() => Date.now() - this.lastKeyNavTime >= 400 && this.isArrowKeyPressed === false),
|
||||||
|
).subscribe(() => {
|
||||||
|
this.pageChange(page);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.pageChange(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyDown(event: KeyboardEvent) {
|
||||||
|
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||||
|
this.isArrowKeyPressed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyUp(event: KeyboardEvent) {
|
||||||
|
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||||
|
this.isArrowKeyPressed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user