MOBILE-2481 course: Add section navigation

main
Pau Ferrer Ocaña 2018-08-09 17:57:39 +02:00
parent 8a2160db17
commit 9b3bd3012e
9 changed files with 56 additions and 10 deletions

View File

@ -67,7 +67,7 @@
<ion-grid text-wrap *ngIf="questions && questions.length && !quizAborted && !showSummary"> <ion-grid text-wrap *ngIf="questions && questions.length && !quizAborted && !showSummary">
<ion-row> <ion-row>
<ion-col *ngIf="previousPage >= 0" > <ion-col *ngIf="previousPage >= 0" >
<button ion-button block icon-start (click)="changePage(previousPage)"> <button ion-button block icon-start color="light" (click)="changePage(previousPage)">
<ion-icon name="arrow-back" md="ios-arrow-back"></ion-icon> <ion-icon name="arrow-back" md="ios-arrow-back"></ion-icon>
{{ 'core.previous' | translate }} {{ 'core.previous' | translate }}
</button> </button>

View File

@ -416,7 +416,7 @@ ion-col ion-select {
} }
:not(.item) ion-select, :not(.item) > * > * > ion-select,
.core-button-select { .core-button-select {
background-color: white; background-color: white;
color: $core-color; color: $core-color;
@ -447,7 +447,7 @@ ion-col ion-select {
} }
.button-inner { .button-inner {
justify-content: space-between; justify-content: start;
} }
.select-icon .select-icon-inner { .select-icon .select-icon-inner {
@ -456,6 +456,8 @@ ion-col ion-select {
ion-icon:last-child { ion-icon:last-child {
@include margin(null, null, null, 5px); @include margin(null, null, null, 5px);
text-align: right;
flex-grow: 2;
} }
} }

View File

@ -2,7 +2,7 @@
<div class="core-tabs-bar" #topTabs [hidden]="!tabs || tabs.length < 2"> <div class="core-tabs-bar" #topTabs [hidden]="!tabs || tabs.length < 2">
<ion-row> <ion-row>
<ion-col class="col-with-arrow" (click)="slidePrev()" no-padding col-1> <ion-col class="col-with-arrow" (click)="slidePrev()" no-padding col-1>
<ion-icon *ngIf="showPrevButton" name="arrow-back"></ion-icon> <ion-icon *ngIf="showPrevButton" name="arrow-back" md="ios-arrow-back"></ion-icon>
</ion-col> </ion-col>
<ion-col no-padding col-10> <ion-col no-padding col-10>
<ion-slides (ionSlideDidChange)="slideChanged()" [slidesPerView]="slidesShown"> <ion-slides (ionSlideDidChange)="slideChanged()" [slidesPerView]="slidesShown">
@ -18,7 +18,7 @@
</ion-slides> </ion-slides>
</ion-col> </ion-col>
<ion-col class="col-with-arrow" (click)="slideNext()" no-padding col-1> <ion-col class="col-with-arrow" (click)="slideNext()" no-padding col-1>
<ion-icon *ngIf="showNextButton" name="arrow-forward"></ion-icon> <ion-icon *ngIf="showNextButton" name="arrow-forward" md="ios-arrow-forward"></ion-icon>
</ion-col> </ion-col>
</ion-row> </ion-row>
</div> </div>

View File

@ -13,7 +13,7 @@
<div *ngIf="course.imageThumb" class="core-course-thumb"> <div *ngIf="course.imageThumb" class="core-course-thumb">
<img [src]="course.imageThumb" core-external-content alt=""/> <img [src]="course.imageThumb" core-external-content alt=""/>
</div> </div>
<ion-item *ngIf="course.progress != null && course.progress >= 0"> <ion-item *ngIf="course.progress != null && course.progress >= 0" class="core-course-progress">
<core-progress-bar [progress]="course.progress"></core-progress-bar> <core-progress-bar [progress]="course.progress"></core-progress-bar>
</ion-item> </ion-item>
</ion-list> </ion-list>
@ -22,8 +22,9 @@
<core-loading [hideUntil]="loaded"> <core-loading [hideUntil]="loaded">
<!-- Section selector. --> <!-- Section selector. -->
<core-dynamic-component [component]="sectionSelectorComponent" [data]="data"> <core-dynamic-component [component]="sectionSelectorComponent" [data]="data">
<div text-wrap *ngIf="displaySectionSelector && sections && sections.length" no-padding class="clearfix"> <div text-wrap *ngIf="displaySectionSelector && sections && sections.length" padding class="clearfix" ion-row justify-content-between>
<button float-start ion-button (click)="showSectionSelector($event)" clear class="core-button-select button-no-uppercase"> <button float-start ion-button icon-start (click)="showSectionSelector($event)" color="light" class="core-button-select button-no-uppercase" ion-col>
<core-icon name="fa-folder"></core-icon>
{{selectedSection && (selectedSection.formattedName || selectedSection.name) || 'core.course.sections' | translate }} {{selectedSection && (selectedSection.formattedName || selectedSection.name) || 'core.course.sections' | translate }}
<ion-icon name="arrow-dropdown" ios="md-arrow-dropdown"></ion-icon> <ion-icon name="arrow-dropdown" ios="md-arrow-dropdown"></ion-icon>
</button> </button>
@ -49,6 +50,17 @@
</core-dynamic-component> </core-dynamic-component>
</div> </div>
</core-loading> </core-loading>
<ion-buttons padding end class="core-course-section-nav-buttons" *ngIf="displaySectionSelector && sections && sections.length">
<button *ngIf="previousSection" ion-button color="light" icon-only (click)="sectionChanged(previousSection)" title="{{ 'core.previous' | translate }}">
<ion-icon name="arrow-back" md="ios-arrow-back"></ion-icon>
<core-format-text class="accesshide" [text]="previousSection.formattedName || previousSection.name"></core-format-text>
</button>
<button *ngIf="nextSection" ion-button icon-only (click)="sectionChanged(nextSection)" title="{{ 'core.next' | translate }}">
<core-format-text class="accesshide" [text]="nextSection.formattedName || nextSection.name"></core-format-text>
<ion-icon name="arrow-forward" md="ios-arrow-forward"></ion-icon>
</button>
</ion-buttons>
</core-dynamic-component> </core-dynamic-component>
<!-- Template to render a section. --> <!-- Template to render a section. -->

View File

@ -55,4 +55,13 @@ core-course-format {
line-height: 44px; line-height: 44px;
} }
} }
.core-course-section-nav-buttons {
.button-inner core-format-text {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
text-transform: none;
}
}
} }

View File

@ -63,6 +63,8 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
displaySectionSelector: boolean; displaySectionSelector: boolean;
selectedSection: any; selectedSection: any;
previousSection: any;
nextSection: any;
allSectionsId: number = CoreCourseProvider.ALL_SECTIONS_ID; allSectionsId: number = CoreCourseProvider.ALL_SECTIONS_ID;
selectOptions: any = {}; selectOptions: any = {};
loaded: boolean; loaded: boolean;
@ -248,6 +250,26 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
this.selectedSection = newSection; this.selectedSection = newSection;
this.data.section = this.selectedSection; this.data.section = this.selectedSection;
// Select next and previous sections to show the arrows.
const i = this.sections.findIndex((value, index) => {
return this.compareSections(value, this.selectedSection);
});
let j;
for (j = i - 1; j >= 1; j--) {
if (!(this.sections[j].visible === 0 || this.sections[j].uservisible === false) && this.sections[j].hasContent) {
break;
}
}
this.previousSection = j >= 1 ? this.sections[j] : null;
for (j = i + 1; j < this.sections.length; j++) {
if (!(this.sections[j].visible === 0 || this.sections[j].uservisible === false) && this.sections[j].hasContent) {
break;
}
}
this.nextSection = j < this.sections.length ? this.sections[j] : null;
if (this.moduleId && typeof previousValue == 'undefined') { if (this.moduleId && typeof previousValue == 'undefined') {
setTimeout(() => { setTimeout(() => {
this.domUtils.scrollToElementBySelector(this.content, '#core-course-module-' + this.moduleId); this.domUtils.scrollToElementBySelector(this.content, '#core-course-module-' + this.moduleId);

View File

@ -11,6 +11,7 @@
<ion-content> <ion-content>
<ng-container *ngFor="let section of sections"> <ng-container *ngFor="let section of sections">
<a ion-item *ngIf="section.hasContent" text-wrap (click)="selectSection(section)" [class.core-primary-item]="selected.id == section.id" [class.item-dimmed]="section.visible === 0 || section.uservisible === false" detail-none> <a ion-item *ngIf="section.hasContent" text-wrap (click)="selectSection(section)" [class.core-primary-item]="selected.id == section.id" [class.item-dimmed]="section.visible === 0 || section.uservisible === false" detail-none>
<core-icon name="fa-folder" item-start></core-icon>
<h2><core-format-text [text]="section.formattedName || section.name"></core-format-text></h2> <h2><core-format-text [text]="section.formattedName || section.name"></core-format-text></h2>
<ion-badge color="secondary" *ngIf="section.visible === 0">{{ 'core.course.nocontentavailable' | translate }}</ion-badge> <ion-badge color="secondary" *ngIf="section.visible === 0">{{ 'core.course.nocontentavailable' | translate }}</ion-badge>
<ion-badge color="secondary" *ngIf="section.availabilityinfo"><core-format-text [text]=" section.availabilityinfo"></core-format-text></ion-badge> <ion-badge color="secondary" *ngIf="section.availabilityinfo"><core-format-text [text]=" section.availabilityinfo"></core-format-text></ion-badge>

View File

@ -6,7 +6,7 @@
<ion-content class="core-center-view"> <ion-content class="core-center-view">
<core-loading [hideUntil]="pageLoaded"> <core-loading [hideUntil]="pageLoaded">
<div class="box"> <div class="box">
<div text-wrap text-center> <div text-wrap text-center margin-bottom>
<!-- Show site logo or a default image. --> <!-- Show site logo or a default image. -->
<img *ngIf="logoUrl" [src]="logoUrl" role="presentation"> <img *ngIf="logoUrl" [src]="logoUrl" role="presentation">
<img *ngIf="!logoUrl" src="assets/img/login_logo.png" class="login-logo" role="presentation"> <img *ngIf="!logoUrl" src="assets/img/login_logo.png" class="login-logo" role="presentation">

View File

@ -5,7 +5,7 @@
</ion-header> </ion-header>
<ion-content padding class="core-center-view"> <ion-content padding class="core-center-view">
<div class="box"> <div class="box">
<div *ngIf="site" text-wrap text-center [ngClass]="{'item-avatar-center': site.avatar}"> <div *ngIf="site" text-wrap text-center margin-bottom [ngClass]="{'item-avatar-center': site.avatar}">
<ion-avatar *ngIf="site.avatar"> <ion-avatar *ngIf="site.avatar">
<!-- Show user avatar. --> <!-- Show user avatar. -->
<img [src]="site.avatar" class="avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullname} }}" role="presentation" onError="this.src='assets/img/user-avatar.png'"> <img [src]="site.avatar" class="avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullname} }}" role="presentation" onError="this.src='assets/img/user-avatar.png'">