Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style(install): Change wording of button to cancel index synchronization. #1567

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a9e5223
feat(install): Replaces index dialog prompt with sidebar buttons
castaway Jan 23, 2024
ad2e8b7
feat(index): Expand index sidebar dialog to cancel download
castaway Jan 31, 2024
a523891
test(search): Ensure search tests have known state before running
castaway Mar 4, 2024
09713f0
style(install): Adjust introductory search index prompt.
gtandersen Mar 9, 2024
da7a055
style(install): Improve formatting of buttons.
gtandersen Mar 9, 2024
3c39c03
Merge branch 'master' into geir/1509_index_sync_modal_adjustment
gtandersen Apr 1, 2024
15e3051
style(install): Adjust indexing prompt for mobile screens.
gtandersen Apr 1, 2024
d7bccd0
test(install): Update test.
gtandersen Apr 2, 2024
8aeeee3
feat(install): Replaces index dialog prompt with sidebar buttons
castaway Jan 23, 2024
60895d9
feat(index): Expand index sidebar dialog to cancel download
castaway Jan 31, 2024
699c2c0
test(search): Ensure search tests have known state before running
castaway Mar 4, 2024
3cd9bde
style(install): Adjust introductory search index prompt.
gtandersen Mar 9, 2024
4318dde
style(install): Improve formatting of buttons.
gtandersen Mar 9, 2024
68d64b6
Merge branch 'castaway/1509_index_sync_modal' into castaway/1509_inde…
castaway Apr 3, 2024
0989d38
Merge pull request #6 from gtandersen/castaway/1509_index_sync_modal
castaway Apr 3, 2024
4cc3c8b
style(install): Improve formatting for mobile phones.
gtandersen Apr 16, 2024
0b4be05
fix(index): Re-prompt local index download on each device
castaway Apr 17, 2024
5b4a3df
style(install): Change wording of button to cancel index synchronizat…
gtandersen Apr 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions e2e/cypress/integration/canvastable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ describe('Selecting rows in canvastable', () => {
it('should select one row', () => {
cy.viewport('iphone-6');
cy.visit('/');
cy.closeWelcomeDialog();

// select
canvas().click({ x: 15, y: 40 });
Expand All @@ -25,7 +24,6 @@ describe('Selecting rows in canvastable', () => {
it('should select multiple rows', () => {
cy.viewport('iphone-6');
cy.visit('/');
cy.closeWelcomeDialog();

canvas().trigger('mousedown', { x: 15, y: 10 });
for (let ndx = 0; ndx <= 5; ndx++) {
Expand Down
2 changes: 0 additions & 2 deletions e2e/cypress/integration/folders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
describe('Folder management', () => {
it('should create folder at root level', () => {
cy.visit('/');
cy.closeWelcomeDialog();

cy.get('#createFolderButton').click();
cy.get('.mat-dialog-title').should('contain', 'Add new folder');
Expand All @@ -16,7 +15,6 @@ describe('Folder management', () => {

it('should empty trash', () => {
cy.visit('/');
cy.closeWelcomeDialog();

cy.contains('mat-tree-node', 'Trash')
.find('button.mat-icon-button[mattooltip="Folder actions"]')
Expand Down
6 changes: 3 additions & 3 deletions e2e/cypress/integration/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
describe('Login', () => {
function expectLoginPage() {
cy.visit('/');
cy.get('#loginHeader h1').should('contain', 'Runbox 7');
cy.get('#loginHeader h1').should('contain', 'Runbox');
}

function enterCredentials() {
Expand All @@ -18,8 +18,8 @@ describe('Login', () => {

function expectWebmail() {
cy.get('#sidenavGreeting').should('contain', '[email protected]');
cy.get('confirm-dialog').should('contain', 'Runbox 7');
cy.get('confirm-dialog .mat-dialog-actions button mat-icon[svgIcon="cancel"]').click().should(() => {
cy.get('#offerLocalIndex').should('contain', 'Runbox');
cy.get('#offerLocalIndex mat-list-item button[data-cy="cancel-button"]').click().should(() => {
expect(JSON.parse(localStorage.getItem('221:Desktop:localSearchPromptDisplayed'))).to.equal('true');
});
}
Expand Down
7 changes: 6 additions & 1 deletion e2e/cypress/integration/search.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
/// <reference types="cypress" />

describe('Search', () => {
beforeEach(() => {
localStorage.setItem('221:Desktop:localSearchPromptDisplayed', JSON.stringify('true'));
localStorage.setItem('221:Mobile:localSearchPromptDisplayed', JSON.stringify('true'));
localStorage.setItem('221:preference_keys', '["Desktop:localSearchPromptDisplayed","Mobile:localSearchPromptDisplayed"]');
});

it('should display multiple search field panel', () => {
cy.visit('/');
cy.closeWelcomeDialog();
cy.get('mat-toolbar mat-form-field button').click();
cy.get('input[data-placeholder=Subject]').type('testsubject');
cy.get('mat-toolbar input[data-placeholder="Start typing to search messages"]')
Expand Down
85 changes: 52 additions & 33 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
</div>
</div>

<mat-divider></mat-divider>


<mat-divider></mat-divider>

<div class="sidenavSubMenu" *ngIf="mobileQuery.matches">
Expand Down Expand Up @@ -121,7 +124,7 @@
</mat-list-item>
</mat-nav-list>

<mat-nav-list *ngIf="(xapianLoaded | async) && !searchService.localSearchActivated && searchService.downloadProgress===null">
<mat-nav-list *ngIf="(xapianLoaded | async) && !searchService.localSearchActivated && searchService.downloadProgress===null && !offerInitialLocalIndex">
<mat-list-item (click)="downloadIndexFromServer()" matTooltip="Synchronize index with your device">
<mat-icon svgIcon="sync" mat-list-icon></mat-icon>
<p mat-line>Synchronize index</p>
Expand Down Expand Up @@ -176,38 +179,54 @@ <h3 class="noMessageSelectedNotification">No Message Selected</h3>
</button>

<ng-container *ngIf="!hasChildRouterOutlet">
<mat-form-field id="searchField" floatLabel="auto"
*ngIf="searchService.downloadProgress===null">
<input matInput #searchInputField type="text"
(focus)="searchTextFieldFocus()"
(blur)="searchTextFieldBlur()" [placeholder]="dynamicSearchFieldPlaceHolder ? dynamicSearchFieldPlaceHolder: 'Start typing to search messages'"
[value]="searchText" (keyup)="searchFor($event.target.value)" matTooltip="Enter one or more search terms, or click the wrench to display the advanced search pane" />
<!-- <app-search-expression-builder
[searchInputField]="searchInputField"
[currentFolder]="selectedFolder"
matSuffix matTooltip="Show search options"></app-search-expression-builder> -->
<button *ngIf="searchText!==''"
mat-icon-button
matSuffix
(click)="showSaveSearchDialog()"
matTooltip="Save search">
<mat-icon svgIcon="content-save"></mat-icon>
</button>
<button *ngIf="!showMultipleSearchFields"
mat-icon-button
matSuffix
(click)="showMultipleSearchFields = true"
matTooltip="Show advanced search pane">
<mat-icon svgIcon="wrench"></mat-icon>
</button>
<button *ngIf="searchText!==''"
mat-icon-button
matSuffix
(click)="searchFor('')"
matTooltip="Clear search">
<mat-icon svgIcon="close"></mat-icon>
</button>
</mat-form-field>
<div id="offerLocalIndex" *ngIf="offerInitialLocalIndex; else searchBar">
<p *ngIf="!mobileQuery.matches">
Runbox will now synchronize with your device to give you an optimal webmail experience. The data can be deleted at any time using the buttons beneath the folder list. <a href="https://help.runbox.com/runbox-7-webmail-new-features/#Synchronized_account_index" target="help">What's this?</a>
</p>
<p *ngIf="mobileQuery.matches">
Runbox will now synchronize with your device. <a href="https://help.runbox.com/runbox-7-webmail-new-features/#Synchronized_account_index" target="help" matTooltip="What's this?">?</a>
</p>
<mat-list>
<mat-list-item>
<button mat-raised-button (click)="downloadIndexFromServer()" matTooltip="Synchronize index with your device" color="primary" [disabled]="searchService.indexDownloadingInProgress">OK!</button>
<button mat-raised-button (click)="cancelOrRefuseLocalIndex()" matTooltip="{{ searchService.indexDownloadingInProgress ? 'Cancel Download' : 'Do not synchronize index'}}" data-cy="cancel-button" color="warn">Cancel</button>
</mat-list-item>
</mat-list>
</div>
<ng-template #searchBar>
<mat-form-field id="searchField" floatLabel="auto"
*ngIf="searchService.downloadProgress===null">
<input matInput #searchInputField type="text"
(focus)="searchTextFieldFocus()"
(blur)="searchTextFieldBlur()" [placeholder]="dynamicSearchFieldPlaceHolder ? dynamicSearchFieldPlaceHolder: 'Start typing to search messages'"
[value]="searchText" (keyup)="searchFor($event.target.value)" matTooltip="Enter one or more search terms, or click the wrench to display the advanced search pane" />
<!-- <app-search-expression-builder
[searchInputField]="searchInputField"
[currentFolder]="selectedFolder"
matSuffix matTooltip="Show search options"></app-search-expression-builder> -->
<button *ngIf="searchText!==''"
mat-icon-button
matSuffix
(click)="showSaveSearchDialog()"
matTooltip="Save search">
<mat-icon svgIcon="content-save"></mat-icon>
</button>
<button *ngIf="!showMultipleSearchFields"
mat-icon-button
matSuffix
(click)="showMultipleSearchFields = true"
matTooltip="Show advanced search pane">
<mat-icon svgIcon="wrench"></mat-icon>
</button>
<button *ngIf="searchText!==''"
mat-icon-button
matSuffix
(click)="searchFor('')"
matTooltip="Clear search">
<mat-icon svgIcon="close"></mat-icon>
</button>
</mat-form-field>
</ng-template>

<button mat-icon-button (click)="updateViewMode('conversations')" *ngIf="!searchtextfieldfocused && viewmode==='singleconversation'"
matTooltip="Back to conversations list">
Expand Down
61 changes: 29 additions & 32 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import { RMM7MessageActions } from './mailviewer/rmm7messageactions';
import { FolderListComponent, CreateFolderEvent, RenameFolderEvent, MoveFolderEvent } from './folder/folder.module';
import { SimpleInputDialog, SimpleInputDialogParams } from './dialog/dialog.module';
import { map, take, skip, mergeMap, filter, tap, throttleTime, debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { ConfirmDialog } from './dialog/confirmdialog.component';
import { WebSocketSearchService } from './websocketsearch/websocketsearch.service';
import { WebSocketSearchMailList } from './websocketsearch/websocketsearchmaillist';

Expand Down Expand Up @@ -98,6 +97,8 @@ export class AppComponent implements OnInit, AfterViewInit, CanvasTableSelectLis
conversationGroupingToolTip = 'Threaded conversation view';
unreadMessagesOnlyCheckbox = false;
unreadOnlyToolTip = 'Unread messages only';
localSearchIndexPrompted = false;
offerInitialLocalIndex = false;

indexDocCount = 0;

Expand Down Expand Up @@ -992,17 +993,39 @@ export class AppComponent implements OnInit, AfterViewInit, CanvasTableSelectLis
}

public downloadIndexFromServer() {
this.preferenceService.set(this.preferenceService.prefGroup, 'localSearchPromptDisplayed', 'true');
this.localSearchIndexPrompted = true;
this.searchService.downloadIndexFromServer().subscribe((res) => {
if (res) {
if (res && !this.searchService.stopIndexDownloadingInProgress) {
this.searchService.downloadPartitions().subscribe(() => {
// this.searchService.openDBOnWorker();
// only done prompting after all partitions fetched
if(this.searchService.stopIndexDownloadingInProgress) {
// decided to stop mid partition download
this.deleteLocalIndex();
}
this.searchService.indexDownloadingInProgress = false;
this.offerInitialLocalIndex = false;
});
} else {
console.log('Index download failed');
console.log('Index download cancelled or failed');
this.deleteLocalIndex();
this.searchService.indexDownloadingInProgress = false;
this.searchService.stopIndexDownloadingInProgress = false;
this.offerInitialLocalIndex = false;
}
});
}

public cancelOrRefuseLocalIndex() {
// Downloading is in progress, pause it:
if (this.searchService.indexDownloadingInProgress) {
this.searchService.stopIndexDownloadingInProgress = true;
}
// User has had the initial prompt, stop asking
this.preferenceService.set(this.preferenceService.prefGroup, 'localSearchPromptDisplayed', 'true');
this.offerInitialLocalIndex = false;
}

singleMailViewerClosed(action: string): void {
this.canvastable.rows.clearOpenedRow();
this.updateUrlFragment();
Expand Down Expand Up @@ -1338,7 +1361,6 @@ export class AppComponent implements OnInit, AfterViewInit, CanvasTableSelectLis
}

promptLocalSearch() {
const localSearchIndexPrompted = this.preferences.get(`${this.preferenceService.prefGroup}:localSearchPromptDisplayed`) === 'true';
console.log('promptLocalSearch');
this.rmmapi.me.pipe(
mergeMap(() => xapianLoadedSubject),
Expand All @@ -1349,35 +1371,10 @@ export class AppComponent implements OnInit, AfterViewInit, CanvasTableSelectLis
}),
filter(xapianLoaded => xapianLoaded ? true : false),
map(() => {
if (localSearchIndexPrompted) {
if (this.localSearchIndexPrompted) {
this.usewebsocketsearch = true;
} else {
const dialogRef = this.dialog.open(ConfirmDialog);
dialogRef.componentInstance.title = 'Welcome to Runbox 7!';
dialogRef.componentInstance.question =
`Runbox 7 will now synchronize with your device to give you an optimal webmail experience.
If you'd later like to remove the data from your device, use the synchronization controls at the bottom of the folder pane.`;
dialogRef.componentInstance.yesOptionTitle = `Sounds good, let's go!`;
dialogRef.componentInstance.noOptionTitle = `Don't synchronize with this device.`;
this.preferenceService.set(this.preferenceService.prefGroup, 'localSearchPromptDisplayed', 'true');

dialogRef.afterClosed().subscribe(res => {
let localIndexDecision = 'clicked-away';
if (res === true) {
localIndexDecision = 'yes';
}
if (res === false) {
localIndexDecision = 'no';
}
this.usage.report(`local-index-decision-${localIndexDecision}`);

if (res) {
this.downloadIndexFromServer();
} else {
this.usewebsocketsearch = true;
}
this.updateTooltips();
});
this.offerInitialLocalIndex = true;
}
})
).subscribe();
Expand Down
10 changes: 9 additions & 1 deletion src/app/xapian/index.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,22 @@ class SearchIndexService {
}

public deleteLocalIndex(): Observable<any> {
if (!this.localSearchActivated) {
// called mid-index load and we hadnt loaded it anyway
// send indexDeleted so the progress dialog closes
console.log('Worker: Tried to delete local index when it is not present');
ctx.postMessage({'action': PostMessageAction.indexDeleted});
return of(null);
}

this.localSearchActivated = false;

return new Observable((observer) => {
console.log('Worker: Closing xapian database');
if (this.api) {
console.log('Worker: API exists?');
this.api.closeXapianDatabase();
}
this.api.closeXapianDatabase();

FS.readdir(XAPIAN_GLASS_WR).forEach((f) => {
if ( f !== '.' && f !== '..') {
Expand Down
Loading
Loading