From 75b0b7a1e1dc1872a28dd6c00465a183c1738b52 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Thu, 5 Aug 2021 12:05:15 +1000 Subject: [PATCH] Move ciphers paging logic from jslib to web (#1094) * Move cipher paging logic from jslib to web * Fix missing constructor argument * Fix protected/private class property * Install ngx-infinite-scroll (moved from jslib) * Update jslib --- jslib | 2 +- package-lock.json | 3 +- package.json | 1 + src/app/vault/ciphers.component.ts | 50 +++++++++++++++++++++++++++++- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/jslib b/jslib index 65c998dd0d..cae26521cc 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 65c998dd0d8798f1ea1ee321bb490d5b94074f0c +Subproject commit cae26521ccf763a8e1d21581ed138a1544469fdf diff --git a/package-lock.json b/package-lock.json index 8f4ebcd366..74727f3fe5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "date-input-polyfill": "^2.14.0", "font-awesome": "4.7.0", "jquery": "3.6.0", + "ngx-infinite-scroll": "10.0.1", "popper.js": "1.16.1", "qrious": "4.0.2", "sweetalert2": "^10.16.6", @@ -79,7 +80,6 @@ "@angular/router": "^11.2.11", "@bitwarden/jslib-common": "file:../common", "duo_web_sdk": "git+https://github.com/duosecurity/duo_web_sdk.git", - "ngx-infinite-scroll": "10.0.1", "rxjs": "6.6.7", "tldjs": "^2.3.1", "zone.js": "0.11.4" @@ -14665,7 +14665,6 @@ "@bitwarden/jslib-common": "file:../common", "@types/duo_web_sdk": "^2.7.1", "duo_web_sdk": "git+https://github.com/duosecurity/duo_web_sdk.git", - "ngx-infinite-scroll": "10.0.1", "rimraf": "^3.0.2", "rxjs": "6.6.7", "tldjs": "^2.3.1", diff --git a/package.json b/package.json index 2086cbf57e..734b25eab3 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "date-input-polyfill": "^2.14.0", "font-awesome": "4.7.0", "jquery": "3.6.0", + "ngx-infinite-scroll": "^10.0.1", "popper.js": "1.16.1", "qrious": "4.0.2", "sweetalert2": "^10.16.6", diff --git a/src/app/vault/ciphers.component.ts b/src/app/vault/ciphers.component.ts index c1d5f1831b..3072f147c4 100644 --- a/src/app/vault/ciphers.component.ts +++ b/src/app/vault/ciphers.component.ts @@ -38,17 +38,22 @@ export class CiphersComponent extends BaseCiphersComponent implements OnDestroy @Output() onCollectionsClicked = new EventEmitter(); @Output() onCloneClicked = new EventEmitter(); + pagedCiphers: CipherView[] = []; + pageSize = 200; cipherType = CipherType; actionPromise: Promise; userHasPremiumAccess = false; + private didScroll = false; + private pagedCiphersCount = 0; + private refreshing = false; + constructor(searchService: SearchService, protected toasterService: ToasterService, protected i18nService: I18nService, protected platformUtilsService: PlatformUtilsService, protected cipherService: CipherService, protected eventService: EventService, protected totpService: TotpService, protected userService: UserService, protected passwordRepromptService: PasswordRepromptService) { super(searchService); - this.pageSize = 200; } async ngOnInit() { @@ -59,6 +64,49 @@ export class CiphersComponent extends BaseCiphersComponent implements OnDestroy this.selectAll(false); } + loadMore() { + if (this.ciphers.length <= this.pageSize) { + return; + } + const pagedLength = this.pagedCiphers.length; + let pagedSize = this.pageSize; + if (this.refreshing && pagedLength === 0 && this.pagedCiphersCount > this.pageSize) { + pagedSize = this.pagedCiphersCount; + } + if (this.ciphers.length > pagedLength) { + this.pagedCiphers = this.pagedCiphers.concat(this.ciphers.slice(pagedLength, pagedLength + pagedSize)); + } + this.pagedCiphersCount = this.pagedCiphers.length; + this.didScroll = this.pagedCiphers.length > this.pageSize; + } + + async refresh() { + try { + this.refreshing = true; + await this.reload(this.filter, this.deleted); + } finally { + this.refreshing = false; + } + } + + isPaging() { + const searching = this.isSearching(); + if (searching && this.didScroll) { + this.resetPaging(); + } + return !searching && this.ciphers.length > this.pageSize; + } + + async resetPaging() { + this.pagedCiphers = []; + this.loadMore(); + } + + async doSearch(indexedCiphers?: CipherView[]) { + this.ciphers = await this.searchService.searchCiphers(this.searchText, [this.filter, this.deletedFilter], indexedCiphers); + this.resetPaging(); + } + launch(uri: string) { this.platformUtilsService.launchUri(uri); }