diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index 24fdfb9ad..7060ff04e 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -84,6 +84,8 @@ import { CircleButtonComponent } from './components/buttons/circle-button/circle import { ChevronButtonComponent } from './components/buttons/chevron-button/chevron-button.component'; import { DictionaryListingScreenComponent } from './screens/admin/dictionary-listing-screen/dictionary-listing-screen.component'; import { CustomTooltipModule } from './common/red-tooltip/custom-tooltip.module'; +import { ScrollingModule } from '@angular/cdk/scrolling'; +import { VirtualScrollComponent } from './utils/virtual-scroll/virtual-scroll.component'; export function HttpLoaderFactory(httpClient: HttpClient) { return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json'); @@ -135,7 +137,8 @@ export function HttpLoaderFactory(httpClient: HttpClient) { UserButtonComponent, CircleButtonComponent, ChevronButtonComponent, - DictionaryListingScreenComponent + DictionaryListingScreenComponent, + VirtualScrollComponent ], imports: [ BrowserModule, diff --git a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html index 5d61e2c8b..36f5ca4b0 100644 --- a/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html +++ b/apps/red-ui/src/app/screens/project-listing-screen/project-listing-screen.component.html @@ -152,6 +152,8 @@ + + diff --git a/apps/red-ui/src/app/utils/sync-scroll.ts b/apps/red-ui/src/app/utils/sync-scroll.ts new file mode 100644 index 000000000..4c888cd4c --- /dev/null +++ b/apps/red-ui/src/app/utils/sync-scroll.ts @@ -0,0 +1,59 @@ +export function syncScroll(elements: HTMLElement[]) { + // clearing existing listeners + for (const element of elements) { + element.removeEventListener('scroll', (element).scrollSync); + } + + // setting-up the new listeners + for (let idx = 0; idx < elements.length; ) { + const loopElement: any = elements[idx++]; + + loopElement.eX = loopElement.eY = 0; + + ((el) => { + el['addEventListener']( + 'scroll', + (el.scrollSync = () => { + let scrollX = el['scrollLeft']; + let scrollY = el['scrollTop']; + + const xRate = scrollX / (el['scrollWidth'] - el['clientWidth']); + const yRate = scrollY / (el['scrollHeight'] - el['clientHeight']); + + const updateX = scrollX !== el.eX; + const updateY = scrollY !== el.eY; + + let otherEl, + i = 0; + + el.eX = scrollX; + el.eY = scrollY; + + for (; i < elements.length; ) { + otherEl = elements[i++]; + if (otherEl !== el) { + if ( + updateX && + Math.round( + otherEl['scrollLeft'] - (scrollX = otherEl.eX = Math.round(xRate * (otherEl['scrollWidth'] - otherEl['clientWidth']))) + ) + ) { + otherEl['scrollLeft'] = scrollX; + } + + if ( + updateY && + Math.round( + otherEl['scrollTop'] - (scrollY = otherEl.eY = Math.round(yRate * (otherEl['scrollHeight'] - otherEl['clientHeight']))) + ) + ) { + otherEl['scrollTop'] = scrollY; + } + } + } + }), + 0 + ); + })(loopElement); + } +} diff --git a/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.html b/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.html new file mode 100644 index 000000000..96c80b38e --- /dev/null +++ b/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.scss b/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.scss new file mode 100644 index 000000000..2c032b127 --- /dev/null +++ b/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.scss @@ -0,0 +1,15 @@ +.virtual-scroll { + // TODO fix this - pass information as input or such + display: none; + position: fixed; + width: 10px; + right: 480px; + bottom: 0; + z-index: 100; + top: 191px; + overflow: auto; + + .virtual { + height: 2000px; + } +} diff --git a/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.ts b/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.ts new file mode 100644 index 000000000..f82ab9f78 --- /dev/null +++ b/apps/red-ui/src/app/utils/virtual-scroll/virtual-scroll.component.ts @@ -0,0 +1,26 @@ +import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { syncScroll } from '../sync-scroll'; + +@Component({ + selector: 'redaction-virtual-scroll', + templateUrl: './virtual-scroll.component.html', + styleUrls: ['./virtual-scroll.component.scss'] +}) +export class VirtualScrollComponent implements AfterViewInit { + @Input() targetQuerySelector = '.red-content'; + @ViewChild('scrollElement') + scrollElement: ElementRef; + content: HTMLElement; + height: number; + factor: number; + + constructor() {} + + ngAfterViewInit(): void { + this.content = document.querySelector(this.targetQuerySelector); + this.factor = this.content.clientHeight / this.scrollElement.nativeElement.clientHeight; + this.height = Math.round(this.content.scrollHeight / this.factor); + console.log(this.factor, this.height); + syncScroll([this.scrollElement.nativeElement, this.content]); + } +}