MOBILE-3335 glossary: Improve UX on browser modes
parent
f27bd969d1
commit
52e6e41fcd
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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'});
|
||||
|
|
Loading…
Reference in New Issue