1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-21 18:53:29 +00:00

infinite scrolling on cipher listing

This commit is contained in:
Kyle Spearrin
2018-04-11 10:23:12 -04:00
parent 3487fdb6e4
commit 744559516d
7 changed files with 252 additions and 42 deletions

View File

@@ -4,6 +4,7 @@ import 'zone.js/dist/zone';
import { ToasterModule } from 'angular2-toaster';
import { Angulartics2Module } from 'angulartics2';
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { AppRoutingModule } from './app-routing.module';
import { ServicesModule } from './services/services.module';
@@ -65,6 +66,7 @@ import { IconComponent } from 'jslib/angular/components/icon.component';
},
}),
ToasterModule,
InfiniteScrollModule,
],
declarations: [
ActionButtonsComponent,

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

View File

@@ -17,8 +17,8 @@
</div>
</header>
<content>
<ng-container *ngIf="(ciphers | searchCiphers: searchText) as searchedCiphers">
<div class="no-items" *ngIf="!searchedCiphers.length">
<ng-container *ngIf="(isSearching() ? (ciphers | searchCiphers: searchText) : pagedCiphers) as filteredCiphers">
<div class="no-items" *ngIf="!filteredCiphers.length">
<i class="fa fa-spinner fa-spin fa-3x" *ngIf="!loaded"></i>
<ng-container *ngIf="loaded">
<p>{{'noItemsInList' | i18n}}</p>
@@ -27,13 +27,15 @@
</button>
</ng-container>
</div>
<div class="box list only-list" *ngIf="searchedCiphers.length > 0">
<div class="box list only-list" *ngIf="filteredCiphers.length > 0"
infiniteScroll [infiniteScrollDistance]="1" [infiniteScrollContainer]="'content'" [fromRoot]="true"
[infiniteScrollDisabled]="isSearching()" (scrolled)="loadMore()">
<div class="box-header">
{{groupingTitle}}
<span class="flex-right">{{searchedCiphers.length}}</span>
<span class="flex-right">{{isSearching() ? filteredCiphers.length : ciphers.length}}</span>
</div>
<div class="box-content">
<app-ciphers-list [ciphers]="searchedCiphers" title="{{'viewItem' | i18n}}"
<app-ciphers-list [ciphers]="filteredCiphers" title="{{'viewItem' | i18n}}"
(onSelected)="selectCipher($event)"
(onDoubleSelected)="launchCipher($event)"></app-ciphers-list>
</div>

View File

@@ -32,6 +32,7 @@ import { CiphersComponent as BaseCiphersComponent } from 'jslib/angular/componen
import { PopupUtilsService } from '../services/popup-utils.service';
const ComponentId = 'CiphersComponent';
const PageSize = 100;
@Component({
selector: 'app-vault-ciphers',
@@ -46,6 +47,9 @@ export class CiphersComponent extends BaseCiphersComponent implements OnInit, On
type: CipherType = null;
selectedTimeout: number;
preventSelected = false;
pagedCiphers: CipherView[] = [];
private didScroll = false;
constructor(cipherService: CipherService, private route: ActivatedRoute,
private router: Router, private location: Location,
@@ -104,6 +108,7 @@ export class CiphersComponent extends BaseCiphersComponent implements OnInit, On
await super.load();
}
this.loadMore();
this.state = (await this.stateService.get<any>(ComponentId)) || {};
if (this.state.searchText) {
this.searchText = this.state.searchText;
@@ -168,6 +173,27 @@ export class CiphersComponent extends BaseCiphersComponent implements OnInit, On
this.location.back();
}
loadMore() {
const pagedLength = this.pagedCiphers.length;
if (this.ciphers.length > pagedLength) {
this.pagedCiphers = this.pagedCiphers.concat(this.ciphers.slice(pagedLength, pagedLength + PageSize));
}
this.didScroll = this.pagedCiphers.length > PageSize;
}
isSearching() {
const searching = this.searchText != null && this.searchText.length > 1;
if (searching && this.didScroll) {
this.resetPaging();
}
return searching;
}
async resetPaging() {
this.pagedCiphers = [];
this.loadMore();
}
private async saveState() {
this.state = {
scrollY: this.popupUtils.getContentScrollY(window),