MOBILE-3335 glossary: Improve UX on browser modes

main
Pau Ferrer Ocaña 2020-02-06 15:02:19 +01:00
parent f27bd969d1
commit 52e6e41fcd
3 changed files with 61 additions and 41 deletions

View File

@ -1,7 +1,10 @@
<!-- Buttons to add to the header. -->
<core-navbar-buttons end>
<button *ngIf="glossary" ion-button icon-only (click)="openModePicker($event)" [attr.aria-label]="'addon.mod_glossary.browsemode' | translate">
<ion-icon name="funnel"></ion-icon>
<button *ngIf="glossary && glossary.browsemodes && glossary.browsemodes.length > 1" ion-button icon-only (click)="openModePicker($event)" [attr.aria-label]="'addon.mod_glossary.browsemode' | translate">
<core-icon name="fa-sort"></core-icon>
</button>
<button *ngIf="glossary" ion-button icon-only (click)="toggleSearch()" [attr.aria-label]="'addon.mod_glossary.bysearch' | translate">
<ion-icon name="search"></ion-icon>
</button>
<core-context-menu>
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" [href]="externalUrl" [iconAction]="'open'"></core-context-menu-item>
@ -29,11 +32,11 @@
<ion-icon name="warning"></ion-icon> {{ 'core.hasdatatosync' | translate:{$a: moduleName} }}
</ion-card>
<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>
<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>
<core-loading [hideUntil]="loaded" class="core-loading-center">
<ion-list *ngIf="viewMode != 'search' && offlineEntries.length > 0">
<ion-list *ngIf="!isSearch && offlineEntries.length > 0">
<ion-item-divider>
{{ 'addon.mod_glossary.entriestobesynced' | translate }}
</ion-item-divider>

View File

@ -25,7 +25,7 @@ import { AddonModGlossarySyncProvider } from '../../providers/sync';
import { AddonModGlossaryModePickerPopoverComponent } from '../mode-picker/mode-picker';
import { AddonModGlossaryPrefetchHandler } from '../../providers/prefetch-handler';
type FetchMode = 'author_all' | 'cat_all' | 'newest_first' | 'recently_updated' | 'search' | 'letter_all';
type FetchMode = 'author_all' | 'cat_all' | 'newest_first' | 'recently_updated' | 'letter_all';
/**
* Component that displays a glossary entry page.
@ -41,8 +41,6 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
component = AddonModGlossaryProvider.COMPONENT;
moduleName = 'glossary';
fetchMode: FetchMode;
viewMode: string;
isSearch = false;
entries = [];
offlineEntries = [];
@ -60,6 +58,10 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
protected showDivider: (entry: any, previous?: any) => boolean;
protected getDivider: (entry: any) => string;
protected addEntryObserver: any;
protected fetchMode: FetchMode;
protected viewMode: string;
protected fetchedEntriesCanLoadMore = false;
protected fetchedEntries = [];
hasOfflineRatings: boolean;
protected ratingOfflineObserver: any;
@ -252,6 +254,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
*/
protected switchMode(mode: FetchMode): void {
this.fetchMode = mode;
this.isSearch = false;
switch (mode) {
case 'author_all':
@ -294,15 +297,6 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
this.getDivider = null;
this.showDivider = (): boolean => false;
break;
case 'search':
// Search for entries.
this.viewMode = 'search';
this.fetchFunction = this.glossaryProvider.getEntriesBySearch;
this.fetchInvalidate = this.glossaryProvider.invalidateEntriesBySearch;
this.fetchArguments = null; // Dynamically set later.
this.getDivider = null;
this.showDivider = (): boolean => false;
break;
case 'letter_all':
default:
// Consider it is 'letter_all'.
@ -341,26 +335,15 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
*/
openModePicker(event: MouseEvent): void {
const popover = this.popoverCtrl.create(AddonModGlossaryModePickerPopoverComponent, {
glossary: this.glossary,
selectedMode: this.fetchMode
browsemodes: this.glossary.browsemodes,
selectedMode: this.isSearch ? '' : this.fetchMode
});
popover.onDidDismiss((newMode: FetchMode) => {
if (newMode === this.fetchMode) {
return;
}
this.loadingMessage = this.translate.instant('core.loading');
this.domUtils.scrollToTop(this.content);
this.switchMode(newMode);
if (this.fetchMode === 'search') {
// If it's not an instant search, then we reset the values.
this.entries = [];
this.canLoadMore = false;
} else {
this.loaded = false;
this.loadContent();
popover.onDidDismiss((mode: FetchMode) => {
if (mode !== this.fetchMode) {
this.changeFetchMode(mode);
} else if (this.isSearch) {
this.toggleSearch();
}
});
@ -369,6 +352,44 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity
});
}
/**
* Toggles between search and fetch mode.
*/
toggleSearch(): void {
if (this.isSearch) {
this.isSearch = false;
this.entries = this.fetchedEntries;
this.canLoadMore = this.fetchedEntriesCanLoadMore;
this.switchMode(this.fetchMode);
} else {
// Search for entries.
this.fetchFunction = this.glossaryProvider.getEntriesBySearch;
this.fetchInvalidate = this.glossaryProvider.invalidateEntriesBySearch;
this.fetchArguments = null; // Dynamically set later.
this.getDivider = null;
this.showDivider = (): boolean => false;
this.isSearch = true;
this.fetchedEntries = this.entries;
this.fetchedEntriesCanLoadMore = this.canLoadMore;
this.canLoadMore = false;
this.entries = [];
}
}
/**
* Change fetch mode
* @param {FetchMode} mode [description]
*/
changeFetchMode(mode: FetchMode): void {
this.isSearch = false;
this.loadingMessage = this.translate.instant('core.loading');
this.domUtils.scrollToTop(this.content);
this.switchMode(mode);
this.loaded = false;
this.loadContent();
}
/**
* Opens an entry.
*

View File

@ -27,14 +27,10 @@ export class AddonModGlossaryModePickerPopoverComponent {
selectedMode: string;
constructor(navParams: NavParams, private viewCtrl: ViewController) {
this.selectedMode = navParams.get('selectedMode');
const glossary = navParams.get('glossary');
this.selectedMode = navParams.get('selectedMode') || '';
const browsemodes = navParams.get('browsemodes');
// Preparing browse modes.
this.modes = [
{key: 'search', langkey: 'addon.mod_glossary.bysearch'}
];
glossary.browsemodes.forEach((mode) => {
browsemodes.forEach((mode) => {
switch (mode) {
case 'letter' :
this.modes.push({key: 'letter_all', langkey: 'addon.mod_glossary.byalphabet'});