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]);
+ }
+}