diff --git a/src/addons/mod/book/components/index/addon-mod-book-index.html b/src/addons/mod/book/components/index/addon-mod-book-index.html index dc1e2dcda..ce5420250 100644 --- a/src/addons/mod/book/components/index/addon-mod-book-index.html +++ b/src/addons/mod/book/components/index/addon-mod-book-index.html @@ -35,20 +35,20 @@ -
- +
+ - -
- {{ 'core.tag.tags' | translate }}: - -
+
+ - +
+ {{ 'core.tag.tags' | translate }}: + +
+
diff --git a/src/addons/mod/book/components/index/index.ts b/src/addons/mod/book/components/index/index.ts index 352b6cdd0..5d3281c25 100644 --- a/src/addons/mod/book/components/index/index.ts +++ b/src/addons/mod/book/components/index/index.ts @@ -26,11 +26,11 @@ import { import { CoreTag, CoreTagItem } from '@features/tag/services/tag'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; -import { Translate } from '@singletons'; import { CoreUtils } from '@services/utils/utils'; import { CoreCourse } from '@features/course/services/course'; import { AddonModBookTocComponent } from '../toc/toc'; import { CoreConstants } from '@/core/constants'; +import { CoreNavigationBarItem } from '@components/navigation-bar/navigation-bar'; /** * Component that displays a book. @@ -45,19 +45,16 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp component = AddonModBookProvider.COMPONENT; chapterContent?: string; - previousChapter?: AddonModBookTocChapter; - nextChapter?: AddonModBookTocChapter; tagsEnabled = false; - displayNavBar = true; - previousNavBarTitle?: string; - nextNavBarTitle?: string; warning = ''; tags?: CoreTagItem[]; + displayNavBar = true; + navigationItems: CoreNavigationBarItem[] = []; + displayTitlesInNavBar = false; protected chapters: AddonModBookTocChapter[] = []; protected currentChapter?: number; protected book?: AddonModBookBookWSData; - protected displayTitlesInNavBar = false; protected contentsMap: AddonModBookContentsMap = {}; constructor( @@ -148,14 +145,18 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp } } - if (typeof this.currentChapter == 'undefined') { + if (this.currentChapter === undefined) { // Load the first chapter. this.currentChapter = AddonModBook.getFirstChapter(this.chapters); } + if (this.currentChapter === undefined) { + return; + } + // Show chapter. try { - await this.loadChapter(this.currentChapter!, refresh); + await this.loadChapter(this.currentChapter, refresh); this.warning = downloadResult?.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) : ''; } catch { @@ -199,15 +200,10 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp this.tags = this.tagsEnabled ? this.contentsMap[this.currentChapter].tags : []; this.chapterContent = content; - this.previousChapter = AddonModBook.getPreviousChapter(this.chapters, chapterId); - this.nextChapter = AddonModBook.getNextChapter(this.chapters, chapterId); - this.previousNavBarTitle = this.previousChapter && this.displayTitlesInNavBar - ? Translate.instant('addon.mod_book.navprevtitle', { $a: this.previousChapter.title }) - : ''; - this.nextNavBarTitle = this.nextChapter && this.displayTitlesInNavBar - ? Translate.instant('addon.mod_book.navnexttitle', { $a: this.nextChapter.title }) - : ''; + if (this.displayNavBar) { + this.navigationItems = this.getNavigationItems(chapterId); + } // Chapter loaded, log view. We don't return the promise because we don't want to block the user for this. await CoreUtils.ignoreErrors(AddonModBook.logView( @@ -216,8 +212,11 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp this.module.name, )); + const currentChapterIndex = this.chapters.findIndex((chapter) => chapter.id == chapterId); + const isLastChapter = currentChapterIndex < 0 || this.chapters[currentChapterIndex + 1] === undefined; + // Module is completed when last chapter is viewed, so we only check completion if the last is reached. - if (!this.nextChapter) { + if (isLastChapter) { CoreCourse.checkModuleCompletion(this.courseId, this.module.completiondata); } } catch (error) { @@ -230,4 +229,19 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp } } + /** + * Converts chapters to navigation items. + * + * @param chapterId Current chapter Id. + * @return Navigation items. + */ + protected getNavigationItems(chapterId: number): CoreNavigationBarItem[] { + return this.chapters.map((chapter) => ({ + item: chapter, + title: chapter.title, + current: chapter.id == chapterId, + enabled: true, + })); + } + } diff --git a/src/addons/mod/book/services/book.ts b/src/addons/mod/book/services/book.ts index edf9c5800..9cd689d84 100644 --- a/src/addons/mod/book/services/book.ts +++ b/src/addons/mod/book/services/book.ts @@ -216,36 +216,6 @@ export class AddonModBookProvider { return chapters[0].id; } - /** - * Get the next chapter to the given one. - * - * @param chapters The chapters list. - * @param chapterId The current chapter. - * @return The next chapter. - */ - getNextChapter(chapters: AddonModBookTocChapter[], chapterId: number): AddonModBookTocChapter | undefined { - const currentChapterIndex = chapters.findIndex((chapter) => chapter.id == chapterId); - - if (currentChapterIndex >= 0 && typeof chapters[currentChapterIndex + 1] != 'undefined') { - return chapters[currentChapterIndex + 1]; - } - } - - /** - * Get the previous chapter to the given one. - * - * @param chapters The chapters list. - * @param chapterId The current chapter. - * @return The next chapter. - */ - getPreviousChapter(chapters: AddonModBookTocChapter[], chapterId: number): AddonModBookTocChapter | undefined { - const currentChapterIndex = chapters.findIndex((chapter) => chapter.id == chapterId); - - if (currentChapterIndex > 0) { - return chapters[currentChapterIndex - 1]; - } - } - /** * Get the book toc as an array. * diff --git a/src/addons/mod/imscp/components/index/addon-mod-imscp-index.html b/src/addons/mod/imscp/components/index/addon-mod-imscp-index.html index 52a6d1eb9..056553b9f 100644 --- a/src/addons/mod/imscp/components/index/addon-mod-imscp-index.html +++ b/src/addons/mod/imscp/components/index/addon-mod-imscp-index.html @@ -40,9 +40,7 @@
- +
diff --git a/src/addons/mod/imscp/components/index/index.scss b/src/addons/mod/imscp/components/index/index.scss index 42c755d23..78b62ae20 100644 --- a/src/addons/mod/imscp/components/index/index.scss +++ b/src/addons/mod/imscp/components/index/index.scss @@ -1,6 +1,4 @@ .addon-mod-imscp-container { - position: absolute; - width: 100%; height: 100%; display: flex; flex-direction: column; diff --git a/src/addons/mod/imscp/components/index/index.ts b/src/addons/mod/imscp/components/index/index.ts index b905e10e8..502478fab 100644 --- a/src/addons/mod/imscp/components/index/index.ts +++ b/src/addons/mod/imscp/components/index/index.ts @@ -14,6 +14,7 @@ import { Component, OnInit, Optional } from '@angular/core'; import { CoreSilentError } from '@classes/errors/silenterror'; +import { CoreNavigationBarItem } from '@components/navigation-bar/navigation-bar'; import { CoreCourseModuleMainResourceComponent } from '@features/course/classes/main-resource-component'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; import { CoreCourse } from '@features/course/services/course'; @@ -32,22 +33,19 @@ import { AddonModImscpTocComponent } from '../toc/toc'; export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceComponent implements OnInit { component = AddonModImscpProvider.COMPONENT; - - items: AddonModImscpTocItem[] = []; - currentItem?: string; src = ''; warning = ''; + navigationItems: CoreNavigationBarItem[] = []; - // Initialize empty previous/next to prevent showing arrows for an instant before they're hidden. - previousItem = ''; - nextItem = ''; + protected items: AddonModImscpTocItem[] = []; + protected currentHref?: string; constructor(@Optional() courseContentsPage?: CoreCourseContentsPage) { super('AddonModImscpIndexComponent', courseContentsPage); } /** - * Component being initialized. + * @inheritdoc */ async ngOnInit(): Promise { super.ngOnInit(); @@ -90,19 +88,19 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom this.items = AddonModImscp.createItemList(contents); - if (this.items.length && typeof this.currentItem == 'undefined') { - this.currentItem = this.items[0].href; + if (this.items.length && this.currentHref === undefined) { + this.currentHref = this.items[0].href; } try { - await this.loadItem(this.currentItem); + await this.loadItemHref(this.currentHref); } catch (error) { CoreDomUtils.showErrorModalDefault(error, 'addon.mod_imscp.deploymenterror', true); throw new CoreSilentError(error); } - this.warning = downloadResult!.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult!.error!) : ''; + this.warning = downloadResult.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) : ''; } finally { // Pass false because downloadResourceIfNeeded already invalidates and refresh data if refresh=true. @@ -113,14 +111,18 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom /** * Loads an item. * - * @param itemId Item ID. + * @param itemHref Item Href. * @return Promise resolved when done. */ - async loadItem(itemId?: string): Promise { - const src = await AddonModImscp.getIframeSrc(this.module, itemId); - this.currentItem = itemId; - this.previousItem = itemId ? AddonModImscp.getPreviousItem(this.items, itemId) : ''; - this.nextItem = itemId ? AddonModImscp.getNextItem(this.items, itemId) : ''; + async loadItemHref(itemHref?: string): Promise { + const src = await AddonModImscp.getIframeSrc(this.module, itemHref); + this.currentHref = itemHref; + + this.navigationItems = this.items.map((item) => ({ + item: item, + current: item.href == this.currentHref, + enabled: !!item.href, + })); if (this.src && src == this.src) { // Re-loading same page. Set it to empty and then re-set the src in the next digest so it detects it has changed. @@ -133,6 +135,15 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom } } + /** + * Loads an item. + * + * @param item Item. + */ + loadItem(item: AddonModImscpTocItem): void { + this.loadItemHref(item.href); + } + /** * Show the TOC. */ @@ -142,12 +153,12 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom component: AddonModImscpTocComponent, componentProps: { items: this.items, - selected: this.currentItem, + selected: this.currentHref, }, }); if (modalData) { - this.loadItem(modalData); + this.loadItemHref(modalData); } } diff --git a/src/addons/mod/imscp/services/imscp.ts b/src/addons/mod/imscp/services/imscp.ts index 746cabcbc..3783cf37d 100644 --- a/src/addons/mod/imscp/services/imscp.ts +++ b/src/addons/mod/imscp/services/imscp.ts @@ -70,63 +70,6 @@ export class AddonModImscpProvider { return items; } - /** - * Get the previous item to the given one. - * - * @param items The items list. - * @param itemId The current item. - * @return The previous item id. - */ - getPreviousItem(items: AddonModImscpTocItem[], itemId: string): string { - const position = this.getItemPosition(items, itemId); - - if (position == -1) { - return ''; - } - - for (let i = position - 1; i >= 0; i--) { - if (items[i] && items[i].href) { - return items[i].href; - } - } - - return ''; - } - - /** - * Get the next item to the given one. - * - * @param items The items list. - * @param itemId The current item. - * @return The next item id. - */ - getNextItem(items: AddonModImscpTocItem[], itemId: string): string { - const position = this.getItemPosition(items, itemId); - - if (position == -1) { - return ''; - } - - for (let i = position + 1; i < items.length; i++) { - if (items[i] && items[i].href) { - return items[i].href; - } - } - - return ''; - } - - /** - * Get the position of a item. - * - * @param items The items list. - * @param itemId The item to search. - * @return The item position. - */ - protected getItemPosition(items: AddonModImscpTocItem[], itemId: string): number { - return items.findIndex((item) => item.href == itemId); - } - /** * Check if we should ommit the file download. * @@ -242,7 +185,7 @@ export class AddonModImscpProvider { const siteId = CoreSites.getCurrentSiteId(); try { - const dirPath = await CoreFilepool.getPackageDirUrlByUrl(siteId, module!.url!); + const dirPath = await CoreFilepool.getPackageDirUrlByUrl(siteId, module.url!); return CoreTextUtils.concatenatePaths(dirPath, itemHref); } catch (error) { diff --git a/src/addons/mod/scorm/pages/player/player.html b/src/addons/mod/scorm/pages/player/player.html index f7f23bd11..73bb4de59 100644 --- a/src/addons/mod/scorm/pages/player/player.html +++ b/src/addons/mod/scorm/pages/player/player.html @@ -21,7 +21,7 @@ - + diff --git a/src/addons/mod/scorm/pages/player/player.ts b/src/addons/mod/scorm/pages/player/player.ts index 9c4bdc9c9..d6dabb226 100644 --- a/src/addons/mod/scorm/pages/player/player.ts +++ b/src/addons/mod/scorm/pages/player/player.ts @@ -13,6 +13,7 @@ // limitations under the License. import { Component, OnInit, OnDestroy } from '@angular/core'; +import { CoreNavigationBarItem } from '@components/navigation-bar/navigation-bar'; import { CoreMainMenuPage } from '@features/mainmenu/pages/menu/menu'; import { CoreNavigator } from '@services/navigator'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; @@ -50,8 +51,6 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy { loadingToc = true; // Whether the TOC is being loaded. toc: AddonModScormTOCScoWithIcon[] = []; // List of SCOs. loaded = false; // Whether the data has been loaded. - previousSco?: AddonModScormScoWithData; // Previous SCO. - nextSco?: AddonModScormScoWithData; // Next SCO. src?: string; // Iframe src. errorMessage?: string; // Error message. accessInfo?: AddonModScormGetScormAccessInformationWSResponse; // Access information. @@ -60,6 +59,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy { incomplete = false; // Whether last attempt is incomplete. cmId!: number; // Course module ID. courseId!: number; // Course ID. + navigationItems: CoreNavigationBarItem[] = []; protected siteId!: string; protected mode!: string; // Mode to play the SCORM. @@ -110,6 +110,8 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy { await this.fetchData(); if (!this.currentSco) { + CoreNavigator.back(); + return; } @@ -176,14 +178,20 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy { }, this.siteId); this.launchNextObserver = CoreEvents.on(AddonModScormProvider.LAUNCH_NEXT_SCO_EVENT, (data) => { - if (data.scormId === this.scorm.id && this.nextSco) { - this.loadSco(this.nextSco); + if (data.scormId === this.scorm.id && this.currentSco) { + const nextSco = AddonModScormHelper.getNextScoFromToc(this.toc, this.currentSco.id); + if (nextSco) { + this.loadSco(nextSco); + } } }, this.siteId); this.launchPrevObserver = CoreEvents.on(AddonModScormProvider.LAUNCH_PREV_SCO_EVENT, (data) => { - if (data.scormId === this.scorm.id && this.previousSco) { - this.loadSco(this.previousSco); + if (data.scormId === this.scorm.id && this.currentSco) { + const previousSco = AddonModScormHelper.getPreviousScoFromToc(this.toc, this.currentSco.id); + if (previousSco) { + this.loadSco(previousSco); + } } }, this.siteId); @@ -211,9 +219,16 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy { * * @param scoId Current SCO ID. */ - protected calculateNextAndPreviousSco(scoId: number): void { - this.previousSco = AddonModScormHelper.getPreviousScoFromToc(this.toc, scoId); - this.nextSco = AddonModScormHelper.getNextScoFromToc(this.toc, scoId); + protected calculateNavigationItems(scoId: number): void { + this.navigationItems = this.toc + .filter((item) => item.isvisible) + .map>((item) => + ({ + item: item, + title: item.title, + current: item.id == scoId, + enabled: !!(item.prereq && item.launch), + })); } /** @@ -398,7 +413,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy { this.currentSco = sco; this.title = sco.title || this.scorm.name; // Try to use SCO title. - this.calculateNextAndPreviousSco(sco.id); + this.calculateNavigationItems(sco.id); // Load the SCO source. this.loadScoSrc(sco); @@ -540,7 +555,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy { } /** - * Component being destroyed. + * @inheritdoc */ ngOnDestroy(): void { // Empty src when leaving the state so unload event is triggered in the iframe. diff --git a/src/addons/mod/scorm/services/scorm-helper.ts b/src/addons/mod/scorm/services/scorm-helper.ts index d62311a2c..ffc21754c 100644 --- a/src/addons/mod/scorm/services/scorm-helper.ts +++ b/src/addons/mod/scorm/services/scorm-helper.ts @@ -280,18 +280,13 @@ export class AddonModScormHelperProvider { * @return Next SCO. */ getNextScoFromToc(toc: AddonModScormScoWithData[], scoId: number): AddonModScormScoWithData | undefined { - for (let i = 0; i < toc.length; i++) { - if (toc[i].id != scoId) { - continue; - } + const currentTocIndex = toc.findIndex((item) => item.id == scoId); - // We found the current SCO. Now search the next visible SCO with fulfilled prerequisites. - for (let j = i + 1; j < toc.length; j++) { - if (toc[j].isvisible && toc[j].prereq && toc[j].launch) { - return toc[j]; - } + // We found the current SCO. Now search the next visible SCO with fulfilled prerequisites. + for (let j = currentTocIndex + 1; j < toc.length; j++) { + if (toc[j].isvisible && toc[j].prereq && toc[j].launch) { + return toc[j]; } - break; } } @@ -303,18 +298,13 @@ export class AddonModScormHelperProvider { * @return Previous SCO. */ getPreviousScoFromToc(toc: AddonModScormScoWithData[], scoId: number): AddonModScormScoWithData | undefined { - for (let i = 0; i < toc.length; i++) { - if (toc[i].id != scoId) { - continue; - } + const currentTocIndex = toc.findIndex((item) => item.id == scoId); - // We found the current SCO. Now let's search the previous visible SCO with fulfilled prerequisites. - for (let j = i - 1; j >= 0; j--) { - if (toc[j].isvisible && toc[j].prereq && toc[j].launch) { - return toc[j]; - } + // We found the current SCO. Now let's search the previous visible SCO with fulfilled prerequisites. + for (let j = currentTocIndex - 1; j >= 0; j--) { + if (toc[j].isvisible && toc[j].prereq && toc[j].launch) { + return toc[j]; } - break; } } diff --git a/src/core/components/navigation-bar/core-navigation-bar.html b/src/core/components/navigation-bar/core-navigation-bar.html index 175e0f549..3f5b6df49 100644 --- a/src/core/components/navigation-bar/core-navigation-bar.html +++ b/src/core/components/navigation-bar/core-navigation-bar.html @@ -1,27 +1,27 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + +

{{currentIndex + 1}} / {{items.length}}

+
+
+ + + + + + +
diff --git a/src/core/components/navigation-bar/navigation-bar.scss b/src/core/components/navigation-bar/navigation-bar.scss index f48edf9b3..b79c274dd 100644 --- a/src/core/components/navigation-bar/navigation-bar.scss +++ b/src/core/components/navigation-bar/navigation-bar.scss @@ -1,7 +1,15 @@ -.core-navigation-bar-arrow { - text-transform: none; - max-width: 100%; - ion-icon { - flex-shrink: 0; +:host { + --background: var(--core-course-module-navigation-background); + + width: 100%; + background-color: var(--background); + display: block; + + .core-navigation-bar-arrow { + text-transform: none; + max-width: 100%; + ion-icon { + flex-shrink: 0; + } } } diff --git a/src/core/components/navigation-bar/navigation-bar.ts b/src/core/components/navigation-bar/navigation-bar.ts index 71f2f28ef..92681ea06 100644 --- a/src/core/components/navigation-bar/navigation-bar.ts +++ b/src/core/components/navigation-bar/navigation-bar.ts @@ -12,48 +12,103 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { CoreTextUtils } from '@services/utils/text'; +import { Component, EventEmitter, Input, OnChanges, Output, SimpleChange } from '@angular/core'; +import { Translate } from '@singletons'; /** - * Component to show a "bar" with arrows to navigate forward/backward and a "info" icon to display more data. + * Component to show a "bar" with arrows to navigate forward/backward and an slider to move around. * * This directive will show two arrows at the left and right of the screen to navigate to previous/next item when clicked. - * If no previous/next item is defined, that arrow won't be shown. It will also show a button to show more info. + * If no previous/next item is defined, that arrow won't be shown. * * Example usage: - * + * */ @Component({ selector: 'core-navigation-bar', templateUrl: 'core-navigation-bar.html', styleUrls: ['navigation-bar.scss'], }) -export class CoreNavigationBarComponent { +export class CoreNavigationBarComponent implements OnChanges { - @Input() previous?: unknown; // Previous item. If not defined, the previous arrow won't be shown. - @Input() previousTitle?: string; // Previous item title. If not defined, only the arrow will be shown. - @Input() next?: unknown; // Next item. If not defined, the next arrow won't be shown. - @Input() nextTitle?: string; // Next item title. If not defined, only the arrow will be shown. - @Input() info = ''; // Info to show when clicking the info button. If not defined, the info button won't be shown. - @Input() title = ''; // Title to show when seeing the info (new page). + @Input() items: CoreNavigationBarItem[] = []; // List of items. + @Input() showTitles = false; // Display titles on buttons. + @Input() previousTranslate = 'core.previous'; // Previous translatable text, can admit $a variable. + @Input() nextTranslate = 'core.next'; // Next translatable text, can admit $a variable. @Input() component?: string; // Component the bar belongs to. @Input() componentId?: number; // Component ID. @Input() contextLevel?: string; // The context level. @Input() contextInstanceId?: number; // The instance ID related to the context. @Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters. - @Output() action?: EventEmitter = - new EventEmitter(); // Function to call when arrow is clicked. Will receive as a param the item to load. - showInfo(): void { - CoreTextUtils.viewText(this.title, this.info, { - component: this.component, - componentId: this.componentId, - filter: true, - contextLevel: this.contextLevel, - instanceId: this.contextInstanceId, - courseId: this.courseId, - }); + previousTitle?: string; // Previous item title. + nextTitle?: string; // Next item title. + previousIndex = -1; // Previous item index. If -1, the previous arrow won't be shown. + nextIndex = -1; // Next item index. If -1, the next arrow won't be shown. + currentIndex = 0; + + // Function to call when arrow is clicked. Will receive as a param the item to load. + @Output() action: EventEmitter = new EventEmitter(); + + /** + * @inheritdoc + */ + ngOnChanges(changes: {[name: string]: SimpleChange}): void { + if (!changes.items || !this.items.length) { + return; + } + + this.currentIndex = this.items.findIndex((item) => item.current); + if (this.currentIndex < 0) { + return; + } + + this.nextIndex = this.items[this.currentIndex + 1]?.enabled ? this.currentIndex + 1 : -1; + if (this.nextIndex >= 0) { + this.nextTitle = Translate.instant(this.nextTranslate, { $a: this.items[this.nextIndex].title || '' }); + } + + this.previousIndex = this.items[this.currentIndex - 1]?.enabled ? this.currentIndex - 1 : -1; + if (this.previousIndex >= 0) { + this.previousTitle = Translate.instant(this.previousTranslate, { $a: this.items[this.previousIndex].title || '' }); + } + } + + /** + * Navigate to an item. + * + * @param itemIndex Selected item index. + */ + navigate(itemIndex: number): void { + if (this.currentIndex == itemIndex || !this.items[itemIndex].enabled) { + return; + } + + this.currentIndex = itemIndex; + this.action.emit(this.items[itemIndex].item); + } + + /** + * Navigate to an item with the range component. + * + * @param target: Element changed. + */ + navigateOnRange(target: HTMLIonRangeElement): void { + const selectedIndex = target.value as number; // Single value, use number. + if (!this.items[selectedIndex].enabled) { + target.value = this.currentIndex; + + return; + } + + this.navigate(selectedIndex); } } + +export type CoreNavigationBarItem = { + item: T; + title?: string; + current: boolean; + enabled: boolean; +}; diff --git a/upgrade.txt b/upgrade.txt index 19393ed60..4f36e38bc 100644 --- a/upgrade.txt +++ b/upgrade.txt @@ -4,6 +4,8 @@ information provided here is intended especially for developers. === 3.9.6 === - The parameters of the functions confirmAndPrefetchCourse and confirmAndPrefetchCourses have changed, they now accept an object with options. +- Component core-navigation-bar changed to add an slider inside. previous, previousTitle, next, nextTitle, info and title have been removed. + Now you have to pass all items and 3 optional params have been added. === 3.9.5 ===