double click to launch cipher

This commit is contained in:
Kyle Spearrin 2018-04-10 23:28:50 -04:00
parent 2ad34c5119
commit 1e1aca2db3
6 changed files with 82 additions and 12 deletions

View File

@ -1,4 +1,5 @@
<a *ngFor="let c of ciphers" (click)="selectCipher(c)" href="#" appStopClick title="{{title}}"
<a *ngFor="let c of ciphers" (click)="selectCipher(c)" (dblclick)="doubleSelectCipher(c)"
href="#" appStopClick title="{{title}}"
class="box-content-row box-content-row-flex">
<div class="row-main">
<app-vault-icon [cipher]="c"></app-vault-icon>

View File

@ -25,6 +25,7 @@ import { PopupUtilsService } from '../services/popup-utils.service';
})
export class CiphersListComponent {
@Output() onSelected = new EventEmitter<CipherView>();
@Output() onDoubleSelected = new EventEmitter<CipherView>();
@Output() onView = new EventEmitter<CipherView>();
@Input() ciphers: CipherView[];
@Input() showView = false;
@ -38,6 +39,10 @@ export class CiphersListComponent {
this.onSelected.emit(c);
}
doubleSelectCipher(c: CipherView) {
this.onDoubleSelected.emit(c);
}
viewCipher(c: CipherView) {
this.onView.emit(c);
}

View File

@ -34,7 +34,8 @@
</div>
<div class="box-content">
<app-ciphers-list [ciphers]="searchedCiphers" title="{{'viewItem' | i18n}}"
(onSelected)="selectCipher($event)"></app-ciphers-list>
(onSelected)="selectCipher($event)"
(onDoubleSelected)="launchCipher($event)"></app-ciphers-list>
</div>
</div>
</ng-container>

View File

@ -1,3 +1,5 @@
import { Angulartics2 } from 'angulartics2';
import { Location } from '@angular/common';
import {
ChangeDetectorRef,
@ -11,6 +13,8 @@ import {
Router,
} from '@angular/router';
import { BrowserApi } from '../../browser/browserApi';
import { FolderService } from 'jslib/abstractions/folder.service';
import { CollectionService } from 'jslib/abstractions/collection.service';
import { CipherService } from 'jslib/abstractions/cipher.service';
@ -40,13 +44,16 @@ export class CiphersComponent extends BaseCiphersComponent implements OnInit, On
showAdd = true;
folderId: string = null;
type: CipherType = null;
selectedTimeout: number;
preventSelected = false;
constructor(cipherService: CipherService, private route: ActivatedRoute,
private router: Router, private location: Location,
private ngZone: NgZone, private broadcasterService: BroadcasterService,
private changeDetectorRef: ChangeDetectorRef, private stateService: StateService,
private popupUtils: PopupUtilsService, private i18nService: I18nService,
private folderService: FolderService, private collectionService: CollectionService) {
private folderService: FolderService, private collectionService: CollectionService,
private analytics: Angulartics2) {
super(cipherService);
}
@ -127,8 +134,29 @@ export class CiphersComponent extends BaseCiphersComponent implements OnInit, On
}
selectCipher(cipher: CipherView) {
super.selectCipher(cipher);
this.router.navigate(['/view-cipher'], { queryParams: { cipherId: cipher.id } });
this.selectedTimeout = window.setTimeout(() => {
if (!this.preventSelected) {
super.selectCipher(cipher);
this.router.navigate(['/view-cipher'], { queryParams: { cipherId: cipher.id } });
}
this.preventSelected = false;
}, 200);
}
async launchCipher(cipher: CipherView) {
if (cipher.type != CipherType.Login || !cipher.login.canLaunch) {
return;
}
if (this.selectedTimeout != null) {
window.clearTimeout(this.selectedTimeout);
}
this.preventSelected = true;
this.analytics.eventTrack.next({ action: 'Launched URI From Listing' });
BrowserApi.createNewTab(cipher.login.uri);
if (this.popupUtils.inPopup(window)) {
BrowserApi.closePopup(window);
}
}
addCipher() {

View File

@ -30,7 +30,8 @@
</div>
<div class="box-content">
<app-ciphers-list [ciphers]="favoriteCiphers" title="{{'viewItem' | i18n}}"
(onSelected)="selectCipher($event)"></app-ciphers-list>
(onSelected)="selectCipher($event)"
(onDoubleSelected)="launchCipher($event)"></app-ciphers-list>
</div>
</div>
<div class="box list">
@ -121,7 +122,8 @@
</div>
<div class="box-content">
<app-ciphers-list [ciphers]="noFolderCiphers" title="{{'viewItem' | i18n}}"
(onSelected)="selectCipher($event)"></app-ciphers-list>
(onSelected)="selectCipher($event)"
(onDoubleSelected)="launchCipher($event)"></app-ciphers-list>
</div>
</div>
</ng-container>
@ -133,7 +135,8 @@
<div class="box list full-list" *ngIf="searchedCiphers.length > 0">
<div class="box-content">
<app-ciphers-list [ciphers]="searchedCiphers" title="{{'viewItem' | i18n}}"
(onSelected)="selectCipher($event)"></app-ciphers-list>
(onSelected)="selectCipher($event)"
(onDoubleSelected)="launchCipher($event)"></app-ciphers-list>
</div>
</div>
</ng-container>

View File

@ -1,3 +1,5 @@
import { Angulartics2 } from 'angulartics2';
import {
ChangeDetectorRef,
Component,
@ -10,6 +12,8 @@ import {
Router,
} from '@angular/router';
import { BrowserApi } from '../../browser/browserApi';
import { CipherType } from 'jslib/enums/cipherType';
import { CollectionView } from 'jslib/models/view/collectionView';
@ -46,13 +50,15 @@ export class GroupingsComponent extends BaseGroupingsComponent implements OnInit
searchText: string;
state: any;
loadedTimeout: number;
selectedTimeout: number;
preventSelected = false;
constructor(collectionService: CollectionService, folderService: FolderService,
private cipherService: CipherService, private router: Router,
private ngZone: NgZone, private broadcasterService: BroadcasterService,
private changeDetectorRef: ChangeDetectorRef, private route: ActivatedRoute,
private stateService: StateService, private popupUtils: PopupUtilsService,
private syncService: SyncService) {
private syncService: SyncService, private analytics: Angulartics2) {
super(collectionService, folderService);
}
@ -85,7 +91,7 @@ export class GroupingsComponent extends BaseGroupingsComponent implements OnInit
if (!this.syncService.syncInProgress) {
this.load();
window.setTimeout(() => this.popupUtils.setContentScrollY(window, this.state.scrollY), 0);
window.setTimeout(() => this.popupUtils.setContentScrollY(window, this.state.scrollY), 0);
} else {
this.loadedTimeout = window.setTimeout(async () => {
if (!this.loaded) {
@ -97,7 +103,12 @@ export class GroupingsComponent extends BaseGroupingsComponent implements OnInit
}
ngOnDestroy() {
window.clearTimeout(this.loadedTimeout);
if (this.loadedTimeout != null) {
window.clearTimeout(this.loadedTimeout);
}
if (this.selectedTimeout != null) {
window.clearTimeout(this.selectedTimeout);
}
this.saveState();
this.broadcasterService.unsubscribe(ComponentId);
}
@ -177,7 +188,28 @@ export class GroupingsComponent extends BaseGroupingsComponent implements OnInit
}
async selectCipher(cipher: CipherView) {
this.router.navigate(['/view-cipher'], { queryParams: { cipherId: cipher.id } });
this.selectedTimeout = window.setTimeout(() => {
if (!this.preventSelected) {
this.router.navigate(['/view-cipher'], { queryParams: { cipherId: cipher.id } });
}
this.preventSelected = false;
}, 200);
}
async launchCipher(cipher: CipherView) {
if (cipher.type != CipherType.Login || !cipher.login.canLaunch) {
return;
}
if (this.selectedTimeout != null) {
window.clearTimeout(this.selectedTimeout);
}
this.preventSelected = true;
this.analytics.eventTrack.next({ action: 'Launched URI From Listing' });
BrowserApi.createNewTab(cipher.login.uri);
if (this.popupUtils.inPopup(window)) {
BrowserApi.closePopup(window);
}
}
async addCipher() {