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:
@@ -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,
|
||||
|
||||
BIN
src/popup/images/fa-globe.png
Normal file
BIN
src/popup/images/fa-globe.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 344 B |
@@ -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>
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user