Skip to content

Commit

Permalink
Add scroll to bottom button and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
minottic committed Feb 1, 2024
1 parent 6675849 commit 4b5765d
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div [ngSwitch]="viewOption" class="logbook-container" (resized)="onResized($event)">
<div [ngSwitch]="viewOption" class="logbook-container" (resized)="onResized()">
<!-- <div #searchBar>
<button (click)="toggleSearch()" >
Search <mat-icon>search</mat-icon>
Expand All @@ -23,10 +23,13 @@
</div>
</div>

<button mat-mini-fab class="float" (click)="scrollToEndOnClick()" [@isAtEnd]="isAtEnd()">
<mat-icon>keyboard_double_arrow_down</mat-icon>
</button>
<div *ngIf="!mobile && !isReadOnly" [ngClass]="isLightMode == true ? 'editor-container' : 'editor-container-no-border'">
<div #editor class="content-editor"
[ngStyle]="{'padding-left':dashboardView === true ? '0px' : '78px', 'width': dashboardView === true ? '97%' : '92%'}"
(resized)="onResized($event)">
(resized)="onResized()">
<div class='accessSettings'>
<span [ngStyle]="{'flex':'1 1 auto'}"></span>
<span matTooltip="ownerGroup">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,10 @@
font-size: initial;
vertical-align: middle;
}

.float {
position: absolute;
margin: -25px;
left: 50%;
transform: translate(-50%, -50%);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ChangeStreamNotification } from '@shared/changestreamnotification.model
import { LogbookDataService } from '@shared/remote-data.service';
import { LogbookScrollService } from '@shared/logbook-scroll.service';
import { AppConfigService } from 'src/app/app-config.service';
import { Renderer2 } from '@angular/core';

class ChangeStreamServiceMock {

Expand Down Expand Up @@ -192,7 +193,6 @@ describe('LogbookItemComponent', () => {
}
}];


const activatedRouteMock = {
parent: { url: of(queryParams) },
snapshot: { queryParams: { id: '1234' } }
Expand All @@ -201,8 +201,12 @@ describe('LogbookItemComponent', () => {

viewsSpy = jasmine.createSpyObj("ViewsService", ["getLogbookViews"]);

logbookItemDataServiceSpy = jasmine.createSpyObj("LogbookItemDataService", ["getDataBuffer", "uploadParagraph"]);
scrollServiceSpy = jasmine.createSpyObj("LogbookScrollService", ["initialize", "updateViewportEstimate", "remove", "appendToEOF", "relax", "isBOF", "isEOF", "prependToBOF"]);
logbookItemDataServiceSpy = jasmine.createSpyObj("LogbookItemDataService", ["uploadParagraph", "getCount"]);
scrollServiceSpy = jasmine.createSpyObj("LogbookScrollService", [
"initialize", "updateViewportEstimate", "remove",
"appendToEOF", "relax", "isBOF", "isEOF",
"prependToBOF", "goToSnippetIndex", "datasource",
]);
scrollServiceSpy.appendToEOF.and.returnValue(of({}));


Expand Down Expand Up @@ -239,6 +243,7 @@ describe('LogbookItemComponent', () => {
component.config = defaultConfig[1].config;
component.configIndex = 1;
component.logbookCount = 10;
component['renderer'] = {setStyle: () => true} as unknown as Renderer2;

fixture.detectChanges();
// views = TestBed.get(ViewsService);
Expand Down Expand Up @@ -595,6 +600,50 @@ describe('LogbookItemComponent', () => {
component["updateSnippetValues"](content, snippet);
expect(snippet.dashboardName).toEqual(content.dashboardName);
expect(snippet.parentId).toEqual(snippet.parentId);
});

[
{input: [0, 0], output: 0},
{input: [1, 0], output: 1},
{input: [0, 1], output: 1},
{input: [1, 1], output: 1},
].forEach((t, i) => {
it(`should test onResized ${i}`, () => {
component._editorHeightRef = 0;
component._snippetHeightRef = 0;
component.snippetContainerRef = {nativeElement: {
parentElement: {parentElement: {parentElement: {parentElement: {offsetHeight: t.input[0]}}}}
}};
component.editorRef = {nativeElement: {offsetHeight: t.input[1]}};
const updateViewHeightsSpy = spyOn(component, 'updateViewHeights').and.callFake(() => true);
component.onResized();
expect(updateViewHeightsSpy).toHaveBeenCalledTimes(t.output);
})
})

it('should test stillToScroll equals old formula', () => {
const autoScrollFraction = 0.4;
const element = {scrollHeight: 10, clientHeight: 5, scrollTop: 4} as Element;
const oldFormula = element.scrollHeight - element.scrollTop - element.clientHeight - autoScrollFraction * element.clientHeight;
expect(component['stillToScroll'](element, autoScrollFraction, 0)).toEqual(oldFormula);
});

it('should test stillToScroll >0', () => {
const element = {scrollHeight: 10, clientHeight: 3, scrollTop: 6} as Element;
expect(component['stillToScroll'](element, 0, 0)).toEqual(1);
});

it('should test stillToScroll <0', () => {
const element = {scrollHeight: 10, clientHeight: 10, scrollTop: 4} as Element;
expect(component['stillToScroll'](element, 0.1, 1)).toEqual(-6);
});

it('should test scrollToEnd', async () => {
spyOn(component["logbookItemDataService"], "getCount").and.resolveTo({count: 10});
const goToSnippetIndexSpy = spyOn(component["logbookScrollService"], "goToSnippetIndex");
await component['scrollToEnd']();
expect(goToSnippetIndexSpy).toHaveBeenCalled();
expect(goToSnippetIndexSpy.calls.mostRecent().args[0]).toEqual(9);
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { ActivatedRoute } from '@angular/router';
import { ViewsService } from '@shared/views.service';
import * as ClassicEditor from '@shared/ckeditor/ckeditor5/build/ckeditor';
import { CKEditorComponent } from '@shared/ckeditor/ckeditor5/build/ckeditor';
import { ResizedEvent } from 'angular-resize-event';
import { MediaObserver } from '@angular/flex-layout';
import { CK5ImageUploadAdapter } from '@shared/ckeditor/ck5-image-upload-adapter';
import { extractNotificationMessage } from '@shared/add-content/add-content.component';
Expand Down Expand Up @@ -81,6 +80,11 @@ import { LinkType } from 'src/app/core/model/paragraphs';
transition('start => end', animate('200ms ease-in')),
transition('end => start', animate('200ms ease-in'))
]),
trigger('isAtEnd', [
state('true', style({ opacity: 0 })),
state('false', style({ opacity: 0.4 })),
transition('true => false', [animate('1s ease-out')])
]),
]
})
export class LogbookItemComponent implements OnInit {
Expand Down Expand Up @@ -132,6 +136,7 @@ export class LogbookItemComponent implements OnInit {
isReadOnly = false;

_snippetHeightRef = 0;
_editorHeightRef = 0;
showSearch = false
showSearchExpanded = false;

Expand Down Expand Up @@ -195,10 +200,10 @@ export class LogbookItemComponent implements OnInit {
if (change[0].mqAlias === 'sm' || change[0].mqAlias === 'xs') {
this.mobile = true;
console.log("mobile");
this.updateViewHeights({});
this.updateViewHeights();
} else {
this.mobile = false;
this.updateViewHeights({});
this.updateViewHeights();
}
}));
}
Expand Down Expand Up @@ -386,15 +391,15 @@ export class LogbookItemComponent implements OnInit {
console.log("appending to EOF")
console.log(notification.content);
await this.logbookScrollService.appendToEOF(notification.content);
let autoScrollEnabled = ((this.snippetContainerRef.nativeElement.scrollHeight - this.snippetContainerRef.nativeElement.scrollTop - this.snippetContainerRef.nativeElement.clientHeight < this.autoScrollFraction * this.snippetContainerRef.nativeElement.clientHeight)) ? true : false;
let autoScrollEnabled = this.isAtEnd(this.autoScrollFraction, 0);
console.log("autoscroll: ", autoScrollEnabled)
if (autoScrollEnabled || this.forceScrollToEnd) {
console.log("scheduling scrolling to EOF");
this.logbookScrollService.scrollToEnd = true;
// await this.logbookScrollService.isLoaded$;
setTimeout(() => {
console.log("scrolling to EOF");
this.snippetContainerRef.nativeElement.scrollTop = this.snippetContainerRef.nativeElement.scrollHeight;
this.scrollWindowToEnd();
}, 50);
}
} else {
Expand All @@ -404,17 +409,7 @@ export class LogbookItemComponent implements OnInit {
}
if (this.forceScrollToEnd) {
console.log("scrolling to new item")
this.forceScrollToEnd = false;
let count = await this.logbookItemDataService.getCount(this.config);
await this.logbookScrollService.goToSnippetIndex(count.count - 1, () => {
this.logbookScrollService.datasource.adapter.relax(() => {
setTimeout(() => {
this.snippetContainerRef.nativeElement.scrollTop = this.snippetContainerRef.nativeElement.scrollHeight;
}, 50);
});

}
);
await this.scrollToEnd();
} else {
console.log(this.childSnippets.toArray());
await this.logbookScrollService.appendToEOF(notification.content);
Expand Down Expand Up @@ -442,6 +437,22 @@ export class LogbookItemComponent implements OnInit {
}
}

private async scrollToEnd() {
this.forceScrollToEnd = false;
const count = await this.logbookItemDataService.getCount(this.config);
await this.logbookScrollService.goToSnippetIndex(count.count - 1, () => {
this.logbookScrollService.datasource.adapter.relax(() => {
setTimeout(() => {
this.scrollWindowToEnd();
}, 50);
});
});
}

private scrollWindowToEnd() {
this.snippetContainerRef.nativeElement.scrollTop = this.snippetContainerRef.nativeElement.scrollHeight;
}

private updateSnippetValues(content: Basesnippets, snippet: Basesnippets) {
for (const key in content) {
snippet[key] = content[key];
Expand Down Expand Up @@ -672,11 +683,13 @@ export class LogbookItemComponent implements OnInit {
this.submitContent(notification);
}

onResized(event: ResizedEvent) {
let _heightRef = this.snippetContainerRef.nativeElement.parentElement.parentElement.parentElement.parentElement.offsetHeight;
if (this._snippetHeightRef != _heightRef) {
onResized() {
const _heightRef = this.snippetContainerRef.nativeElement.parentElement.parentElement.parentElement.parentElement.offsetHeight;
const _editorHeight = this.editorRef?.nativeElement?.offsetHeight;
if (this._snippetHeightRef != _heightRef || this._editorHeightRef != _editorHeight) {
this._snippetHeightRef = _heightRef;
this.updateViewHeights(event)
this._editorHeightRef = _editorHeight;
this.updateViewHeights();
}

// console.log(this.snippetContainerRef.nativeElement.parentElement.parentElement.parentElement.parentElement.offsetHeight);
Expand All @@ -686,7 +699,7 @@ export class LogbookItemComponent implements OnInit {
// }, 10);
}

updateViewHeights(event) {
updateViewHeights() {
if (this.editorRef) {
let offset = this.mobile ? 210 - 28 : (this.dashboardView ? 130 - 28 : 195 - 25);
let snippetHeight: number;
Expand All @@ -704,7 +717,7 @@ export class LogbookItemComponent implements OnInit {
ngAfterViewInit(): void {
//Called after ngAfterContentInit when the component's view has been initialized. Applies to components only.
//Add 'implements AfterViewInit' to the class.
this.updateViewHeights({});
this.updateViewHeights();
this.cdr.detectChanges();
}

Expand Down Expand Up @@ -751,6 +764,23 @@ export class LogbookItemComponent implements OnInit {
})
}

isAtEnd(scrollPortion = 0, offset = 1) {
const element = this.snippetContainerRef?.nativeElement;
if (element)
return this.stillToScroll(element, scrollPortion, offset) <= 0;
}

private stillToScroll(element: Element, scrollPortion: number, offset: number) {
return element.scrollHeight - element.clientHeight * (1 + scrollPortion) - element.scrollTop - offset;
}

scrollToEndOnClick() {
if (this.logbookScrollService.isEOF)
this.scrollWindowToEnd();
else
this.scrollToEnd();
}

addContent(isMessage = false) {
this.forceScrollToEnd = true;
console.log(this.editorContentRef.editorInstance.prel_filestorage);
Expand Down

0 comments on commit 4b5765d

Please sign in to comment.