Skip to content

Commit 52e6e41

Browse files
committed
MOBILE-3335 glossary: Improve UX on browser modes
1 parent f27bd96 commit 52e6e41

File tree

3 files changed

+61
-41
lines changed

3 files changed

+61
-41
lines changed

src/addon/mod/glossary/components/index/addon-mod-glossary-index.html

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<!-- Buttons to add to the header. -->
22
<core-navbar-buttons end>
3-
<button *ngIf="glossary" ion-button icon-only (click)="openModePicker($event)" [attr.aria-label]="'addon.mod_glossary.browsemode' | translate">
4-
<ion-icon name="funnel"></ion-icon>
3+
<button *ngIf="glossary && glossary.browsemodes && glossary.browsemodes.length > 1" ion-button icon-only (click)="openModePicker($event)" [attr.aria-label]="'addon.mod_glossary.browsemode' | translate">
4+
<core-icon name="fa-sort"></core-icon>
5+
</button>
6+
<button *ngIf="glossary" ion-button icon-only (click)="toggleSearch()" [attr.aria-label]="'addon.mod_glossary.bysearch' | translate">
7+
<ion-icon name="search"></ion-icon>
58
</button>
69
<core-context-menu>
710
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
@@ -29,11 +32,11 @@
2932
<ion-icon name="warning"></ion-icon> {{ 'core.hasdatatosync' | translate:{$a: moduleName} }}
3033
</ion-card>
3134

32-
<core-search-box *ngIf="viewMode == 'search'" (onSubmit)="search($event)" [placeholder]="'addon.mod_glossary.searchquery' | translate" [autoFocus]="true" [lengthCheck]="2" [showClear]="false" searchArea="AddonModGlossary-{{module.id}}"></core-search-box>
35+
<core-search-box *ngIf="isSearch" (onSubmit)="search($event)" [placeholder]="'addon.mod_glossary.searchquery' | translate" [autoFocus]="true" [lengthCheck]="2" [showClear]="false" searchArea="AddonModGlossary-{{module.id}}"></core-search-box>
3336

3437
<core-loading [hideUntil]="loaded" class="core-loading-center">
3538

36-
<ion-list *ngIf="viewMode != 'search' && offlineEntries.length > 0">
39+
<ion-list *ngIf="!isSearch && offlineEntries.length > 0">
3740
<ion-item-divider>
3841
{{ 'addon.mod_glossary.entriestobesynced' | translate }}
3942
</ion-item-divider>

src/addon/mod/glossary/components/index/index.ts

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { AddonModGlossarySyncProvider } from '../../providers/sync';
2525
import { AddonModGlossaryModePickerPopoverComponent } from '../mode-picker/mode-picker';
2626
import { AddonModGlossaryPrefetchHandler } from '../../providers/prefetch-handler';
2727

28-
type FetchMode = 'author_all' | 'cat_all' | 'newest_first' | 'recently_updated' | 'search' | 'letter_all';
28+
type FetchMode = 'author_all' | 'cat_all' | 'newest_first' | 'recently_updated' | 'letter_all';
2929

3030
/**
3131
* Component that displays a glossary entry page.
@@ -41,8 +41,6 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
4141
component = AddonModGlossaryProvider.COMPONENT;
4242
moduleName = 'glossary';
4343

44-
fetchMode: FetchMode;
45-
viewMode: string;
4644
isSearch = false;
4745
entries = [];
4846
offlineEntries = [];
@@ -60,6 +58,10 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
6058
protected showDivider: (entry: any, previous?: any) => boolean;
6159
protected getDivider: (entry: any) => string;
6260
protected addEntryObserver: any;
61+
protected fetchMode: FetchMode;
62+
protected viewMode: string;
63+
protected fetchedEntriesCanLoadMore = false;
64+
protected fetchedEntries = [];
6365

6466
hasOfflineRatings: boolean;
6567
protected ratingOfflineObserver: any;
@@ -252,6 +254,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
252254
*/
253255
protected switchMode(mode: FetchMode): void {
254256
this.fetchMode = mode;
257+
this.isSearch = false;
255258

256259
switch (mode) {
257260
case 'author_all':
@@ -294,15 +297,6 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
294297
this.getDivider = null;
295298
this.showDivider = (): boolean => false;
296299
break;
297-
case 'search':
298-
// Search for entries.
299-
this.viewMode = 'search';
300-
this.fetchFunction = this.glossaryProvider.getEntriesBySearch;
301-
this.fetchInvalidate = this.glossaryProvider.invalidateEntriesBySearch;
302-
this.fetchArguments = null; // Dynamically set later.
303-
this.getDivider = null;
304-
this.showDivider = (): boolean => false;
305-
break;
306300
case 'letter_all':
307301
default:
308302
// Consider it is 'letter_all'.
@@ -341,26 +335,15 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
341335
*/
342336
openModePicker(event: MouseEvent): void {
343337
const popover = this.popoverCtrl.create(AddonModGlossaryModePickerPopoverComponent, {
344-
glossary: this.glossary,
345-
selectedMode: this.fetchMode
338+
browsemodes: this.glossary.browsemodes,
339+
selectedMode: this.isSearch ? '' : this.fetchMode
346340
});
347341

348-
popover.onDidDismiss((newMode: FetchMode) => {
349-
if (newMode === this.fetchMode) {
350-
return;
351-
}
352-
353-
this.loadingMessage = this.translate.instant('core.loading');
354-
this.domUtils.scrollToTop(this.content);
355-
this.switchMode(newMode);
356-
357-
if (this.fetchMode === 'search') {
358-
// If it's not an instant search, then we reset the values.
359-
this.entries = [];
360-
this.canLoadMore = false;
361-
} else {
362-
this.loaded = false;
363-
this.loadContent();
342+
popover.onDidDismiss((mode: FetchMode) => {
343+
if (mode !== this.fetchMode) {
344+
this.changeFetchMode(mode);
345+
} else if (this.isSearch) {
346+
this.toggleSearch();
364347
}
365348
});
366349

@@ -369,6 +352,44 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
369352
});
370353
}
371354

355+
/**
356+
* Toggles between search and fetch mode.
357+
*/
358+
toggleSearch(): void {
359+
if (this.isSearch) {
360+
this.isSearch = false;
361+
this.entries = this.fetchedEntries;
362+
this.canLoadMore = this.fetchedEntriesCanLoadMore;
363+
this.switchMode(this.fetchMode);
364+
} else {
365+
// Search for entries.
366+
this.fetchFunction = this.glossaryProvider.getEntriesBySearch;
367+
this.fetchInvalidate = this.glossaryProvider.invalidateEntriesBySearch;
368+
this.fetchArguments = null; // Dynamically set later.
369+
this.getDivider = null;
370+
this.showDivider = (): boolean => false;
371+
this.isSearch = true;
372+
373+
this.fetchedEntries = this.entries;
374+
this.fetchedEntriesCanLoadMore = this.canLoadMore;
375+
this.canLoadMore = false;
376+
this.entries = [];
377+
}
378+
}
379+
380+
/**
381+
* Change fetch mode
382+
* @param {FetchMode} mode [description]
383+
*/
384+
changeFetchMode(mode: FetchMode): void {
385+
this.isSearch = false;
386+
this.loadingMessage = this.translate.instant('core.loading');
387+
this.domUtils.scrollToTop(this.content);
388+
this.switchMode(mode);
389+
this.loaded = false;
390+
this.loadContent();
391+
}
392+
372393
/**
373394
* Opens an entry.
374395
*

src/addon/mod/glossary/components/mode-picker/mode-picker.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,10 @@ export class AddonModGlossaryModePickerPopoverComponent {
2727
selectedMode: string;
2828

2929
constructor(navParams: NavParams, private viewCtrl: ViewController) {
30-
this.selectedMode = navParams.get('selectedMode');
31-
const glossary = navParams.get('glossary');
30+
this.selectedMode = navParams.get('selectedMode') || '';
31+
const browsemodes = navParams.get('browsemodes');
3232

33-
// Preparing browse modes.
34-
this.modes = [
35-
{key: 'search', langkey: 'addon.mod_glossary.bysearch'}
36-
];
37-
glossary.browsemodes.forEach((mode) => {
33+
browsemodes.forEach((mode) => {
3834
switch (mode) {
3935
case 'letter' :
4036
this.modes.push({key: 'letter_all', langkey: 'addon.mod_glossary.byalphabet'});

0 commit comments

Comments
 (0)