forked from EVOgeek/Vmeda.Online
		
	MOBILE-4283 quiz: Allow students to hide timer
This commit is contained in:
		
							parent
							
								
									670bb10330
								
							
						
					
					
						commit
						573af7c513
					
				| @ -27,15 +27,15 @@ | |||||||
|         margin-right: 2px; |         margin-right: 2px; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     core-timer .core-timer { |     core-timer { | ||||||
|         &.core-timer-under-300 { |         &.core-timer-under-300 { | ||||||
|             background-color: var(--danger-tint); |             --timer-background: var(--danger-tint); | ||||||
|             color: var(--danger-shade); |             --timer-text-color: var(--danger-shade); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         &.core-timer-under-900 { |         &.core-timer-under-900 { | ||||||
|             background-color: var(--warning-tint); |             --timer-background: var(--warning-tint); | ||||||
|             color: var(--warning-shade); |             --timer-text-color: var(--warning-shade); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -22,7 +22,7 @@ | |||||||
|             <!-- @todo plagiarism_print_disclosure --> |             <!-- @todo plagiarism_print_disclosure --> | ||||||
|             <core-timer *ngIf="timeLimitEndTime > 0" [endTime]="timeLimitEndTime" (finished)="timeUp()" timeUpText="00:00:00" |             <core-timer *ngIf="timeLimitEndTime > 0" [endTime]="timeLimitEndTime" (finished)="timeUp()" timeUpText="00:00:00" | ||||||
|                 [timerText]="'addon.mod_assign.assigntimeleft' | translate" [align]="'center'" [timeLeftClassThreshold]="-1" |                 [timerText]="'addon.mod_assign.assigntimeleft' | translate" [align]="'center'" [timeLeftClassThreshold]="-1" | ||||||
|                 [underTimeClassThresholds]="[300, 900]" class="ion-margin-horizontal"> |                 [underTimeClassThresholds]="[300, 900]"> | ||||||
|             </core-timer> |             </core-timer> | ||||||
| 
 | 
 | ||||||
|             <!-- Assign activity instructions and attachments if needed. --> |             <!-- Assign activity instructions and attachments if needed. --> | ||||||
|  | |||||||
| @ -1,17 +1,13 @@ | |||||||
| :host ::ng-deep { | :host { | ||||||
|     core-timer { |     core-timer { | ||||||
|         display: block; |  | ||||||
| 
 |  | ||||||
|         .core-timer { |  | ||||||
|         &.core-timer-under-300 { |         &.core-timer-under-300 { | ||||||
|                 background-color: var(--danger-tint); |             --timer-background: var(--danger-tint); | ||||||
|                 color: var(--danger-shade); |             --timer-text-color: var(--danger-shade); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         &.core-timer-under-900 { |         &.core-timer-under-900 { | ||||||
|                 background-color: var(--warning-tint); |             --timer-background: var(--warning-tint); | ||||||
|                 color: var(--warning-shade); |             --timer-text-color: var(--warning-shade); | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -22,13 +22,9 @@ | |||||||
|             </ion-button> |             </ion-button> | ||||||
|         </ion-buttons> |         </ion-buttons> | ||||||
|     </ion-toolbar> |     </ion-toolbar> | ||||||
|     <!-- Navigation arrows and time left. --> |     <core-timer *ngIf="loaded && endTime && questions.length && !quizAborted && !showSummary" [endTime]="endTime" (finished)="timeUp()" | ||||||
|     <ion-toolbar *ngIf="loaded && endTime && questions.length && !quizAborted && !showSummary" color="light"> |         [timerText]="'addon.mod_quiz.timeleft' | translate" [hiddable]="true"> | ||||||
|         <ion-title> |  | ||||||
|             <core-timer [endTime]="endTime" (finished)="timeUp()" [timerText]="'addon.mod_quiz.timeleft' | translate" [align]="'center'"> |  | ||||||
|     </core-timer> |     </core-timer> | ||||||
|         </ion-title> |  | ||||||
|     </ion-toolbar> |  | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content class="limited-width"> | <ion-content class="limited-width"> | ||||||
|     <core-loading [hideUntil]="loaded" class="has-spacer"> |     <core-loading [hideUntil]="loaded" class="has-spacer"> | ||||||
|  | |||||||
| @ -9,22 +9,14 @@ $quiz-timer-iterations: 15 !default; | |||||||
|         margin-bottom: 2px; |         margin-bottom: 2px; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ion-content ion-toolbar { |     core-timer { | ||||||
|         border-bottom: 1px solid var(--stroke); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     core-timer ::ng-deep { |  | ||||||
|         .core-timer { |  | ||||||
|         // Make the timer go red when it's reaching 0. |         // Make the timer go red when it's reaching 0. | ||||||
|         @for $i from 0 through $quiz-timer-iterations { |         @for $i from 0 through $quiz-timer-iterations { | ||||||
|             &.core-timer-timeleft-#{$i} { |             &.core-timer-timeleft-#{$i} { | ||||||
|                     background-color: rgba($quiz-timer-warn-color, 1 - ($i / $quiz-timer-iterations)) !important; |                 $timer-background: rgba($quiz-timer-warn-color, 1 - ($i / $quiz-timer-iterations)); | ||||||
| 
 |                 --timer-background: #{$timer-background}; | ||||||
|                 @if $i <= $quiz-timer-iterations / 2 { |                 @if $i <= $quiz-timer-iterations / 2 { | ||||||
|                         label, span, ion-icon { |                     --timer-text-color: var(--white); | ||||||
|                             color: var(--white); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -1,21 +1,32 @@ | |||||||
| <ion-item *ngIf="mode !== modeBasic" class="core-timer" role="timer" | <ng-container *ngIf="timeLeft !== undefined"> | ||||||
|     [ngClass]="{'ion-text-center': align == 'center', 'ion-text-end': align == 'right'}"> |     <ion-item *ngIf="mode !== modeBasic" class="core-timer" role="timer" [attr.aria-label]="timerText"> | ||||||
|     <ion-icon name="fas-clock" slot="start" aria-hidden="true"></ion-icon> |         <ion-label class="ion-justify-content-{{align}}"> | ||||||
|     <ion-label> |  | ||||||
|             <ng-container *ngTemplateOutlet="timerTemplate"></ng-container> |             <ng-container *ngTemplateOutlet="timerTemplate"></ng-container> | ||||||
|         </ion-label> |         </ion-label> | ||||||
|     </ion-item> |     </ion-item> | ||||||
| 
 | 
 | ||||||
| <div *ngIf="mode === modeBasic" class="core-timer ion-padding" role="timer" |     <div *ngIf="mode === modeBasic" class="core-timer ion-padding ion-justify-content-{{align}}" role="timer" [attr.aria-label]="timerText"> | ||||||
|     [ngClass]="{'ion-text-center': align == 'center', 'ion-text-end': align == 'right'}"> |  | ||||||
|         <ng-container *ngTemplateOutlet="timerTemplate"></ng-container> |         <ng-container *ngTemplateOutlet="timerTemplate"></ng-container> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <ng-template #timerTemplate> |     <ng-template #timerTemplate> | ||||||
|  |         <ng-container *ngIf="timeLeft > 0"> | ||||||
|  |             <div class="ion-text-wrap"> | ||||||
|                 <span *ngIf="timerText" class="core-timer-text">{{ timerText }}</span> |                 <span *ngIf="timerText" class="core-timer-text">{{ timerText }}</span> | ||||||
|     <span *ngIf="timeLeft && timeLeft > 0" class="core-timer-time-left">{{ timeLeft | coreSecondsToHMS }}</span> |                 <span *ngIf="showTimeLeft" class="core-timer-time-left"> | ||||||
|     <span class="core-timesup" *ngIf="timeLeft !== undefined && timeLeft <= 0"> |                     {{ timeLeft | coreSecondsToHMS }} | ||||||
|  |                 </span> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <div *ngIf="hiddable" class="core-timer-visibility"> | ||||||
|  |                 ( <button class="as-link" *ngIf="showTimeLeft" (click)="toggleTimeLeftVisibility()">{{ 'core.hide' | translate }}</button> | ||||||
|  |                 <button class="as-link" *ngIf="!showTimeLeft" (click)="toggleTimeLeftVisibility()">{{ 'core.show' | translate }}</button> ) | ||||||
|  |             </div> | ||||||
|  |         </ng-container> | ||||||
|  | 
 | ||||||
|  |         <div class="core-timesup" *ngIf="timeLeft <= 0"> | ||||||
|             <ng-container *ngIf="timeUpText">{{ timeUpText }}</ng-container> |             <ng-container *ngIf="timeUpText">{{ timeUpText }}</ng-container> | ||||||
|             <ng-container *ngIf="!timeUpText">{{ 'core.timesup' | translate }}</ng-container> |             <ng-container *ngIf="!timeUpText">{{ 'core.timesup' | translate }}</ng-container> | ||||||
|     </span> |         </div> | ||||||
|     </ng-template> |     </ng-template> | ||||||
|  | </ng-container> | ||||||
|  | |||||||
| @ -1,14 +1,40 @@ | |||||||
| :host { | :host { | ||||||
|     .core-timer { |     --timer-background: transparent; | ||||||
|         --background: transparent !important; |  | ||||||
|         border-radius: var(--big-radius); |  | ||||||
| 
 | 
 | ||||||
|  |     .core-timer { | ||||||
|         .core-timer-time-left, .core-timesup { |         .core-timer-time-left, .core-timesup { | ||||||
|             font-weight: bold; |             font-weight: bold; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         span { |         .core-timesup { | ||||||
|             margin-right: 5px; |             flex-grow: 1; | ||||||
|  |             text-align: center; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ion-item.core-timer { | ||||||
|  |         --background: var(--timer-background); | ||||||
|  |         --color: var(--timer-text-color, var(--text-color)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     div.core-timer { | ||||||
|  |         background: var(--timer-background); | ||||||
|  |         color: var(--timer-text-color, var(--text-color)); | ||||||
|  |         border-radius: var(--big-radius); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     button { | ||||||
|  |         color: var(--timer-text-color, var(--core-link-color)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ion-item.core-timer ion-label, | ||||||
|  |     div.core-timer { | ||||||
|  |         display: flex; | ||||||
|  |         align-items: center; | ||||||
|  | 
 | ||||||
|  |         .core-timer-visibility { | ||||||
|  |             flex-grow: 1; | ||||||
|  |             text-align: end; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -29,11 +29,12 @@ import { CoreTimeUtils } from '@services/utils/time'; | |||||||
| }) | }) | ||||||
| export class CoreTimerComponent implements OnInit, OnDestroy { | export class CoreTimerComponent implements OnInit, OnDestroy { | ||||||
| 
 | 
 | ||||||
|     @Input() endTime?: string | number; // Timestamp (in seconds) when the timer should end.
 |     @Input() endTime = 0; // Timestamp (in seconds) when the timer should end.
 | ||||||
|     @Input() timerText?: string; // Text to show next to the timer. If not defined, no text shown.
 |     @Input() timerText?: string; // Text to show next to the timer. If not defined, no text shown.
 | ||||||
|     @Input() timeLeftClass?: string; // Name of the class to apply with each second. By default, 'core-timer-timeleft-'.
 |     @Input() timeLeftClass?: string; // Name of the class to apply with each second. By default, 'core-timer-timeleft-'.
 | ||||||
|     @Input() timeLeftClassThreshold = 100; // Number of seconds to start adding the timeLeftClass. Set it to -1 to not add it.
 |     @Input() timeLeftClassThreshold = 100; // Number of seconds to start adding the timeLeftClass. Set it to -1 to not add it.
 | ||||||
|     @Input() align?: string; // Where to align the time and text. Defaults to 'left'. Other values: 'center', 'right'.
 |     @Input() align = 'start'; // Where to align the time and text. Defaults to 'start'. Other values: 'center', 'end'.
 | ||||||
|  |     @Input() hiddable = false; // Whether the user can hide the time left.
 | ||||||
|     @Input() timeUpText?: string; // Text to show when the timer reaches 0. If not defined, 'core.timesup'.
 |     @Input() timeUpText?: string; // Text to show when the timer reaches 0. If not defined, 'core.timesup'.
 | ||||||
|     @Input() mode: CoreTimerMode = CoreTimerMode.ITEM; // How to display data.
 |     @Input() mode: CoreTimerMode = CoreTimerMode.ITEM; // How to display data.
 | ||||||
|     @Input() underTimeClassThresholds = []; // Number of seconds to add the class 'core-timer-under-'.
 |     @Input() underTimeClassThresholds = []; // Number of seconds to add the class 'core-timer-under-'.
 | ||||||
| @ -41,6 +42,7 @@ export class CoreTimerComponent implements OnInit, OnDestroy { | |||||||
| 
 | 
 | ||||||
|     timeLeft?: number; // Seconds left to end.
 |     timeLeft?: number; // Seconds left to end.
 | ||||||
|     modeBasic = CoreTimerMode.BASIC; |     modeBasic = CoreTimerMode.BASIC; | ||||||
|  |     showTimeLeft = true; | ||||||
| 
 | 
 | ||||||
|     protected timeInterval?: number; |     protected timeInterval?: number; | ||||||
|     protected element?: HTMLElement; |     protected element?: HTMLElement; | ||||||
| @ -54,18 +56,21 @@ export class CoreTimerComponent implements OnInit, OnDestroy { | |||||||
|      */ |      */ | ||||||
|     ngOnInit(): void { |     ngOnInit(): void { | ||||||
|         const timeLeftClass = this.timeLeftClass || 'core-timer-timeleft-'; |         const timeLeftClass = this.timeLeftClass || 'core-timer-timeleft-'; | ||||||
|         const endTime = Math.round(Number(this.endTime)); |         const endTime = Math.round(this.endTime); | ||||||
|         this.underTimeClassThresholds.sort((a, b) => a - b); // Sort by increase order.
 |         this.underTimeClassThresholds.sort((a, b) => a - b); // Sort by increase order.
 | ||||||
| 
 | 
 | ||||||
|         if (!endTime) { |         // @deprecated since 4.3. Use start/end instead.
 | ||||||
|             return; |         if (this.align === 'left') { | ||||||
|  |             this.align = 'start'; | ||||||
|  |         } else if (this.align === 'right') { | ||||||
|  |             this.align = 'end'; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let container: HTMLElement | undefined; |         let container: HTMLElement | undefined; | ||||||
| 
 | 
 | ||||||
|         // Check time left every 200ms.
 |         // Check time left every 200ms.
 | ||||||
|         this.timeInterval = window.setInterval(() => { |         this.timeInterval = window.setInterval(() => { | ||||||
|             container = container || this.elementRef.nativeElement.querySelector('.core-timer'); |             container = container || this.elementRef.nativeElement; | ||||||
|             this.timeLeft = Math.max(endTime - CoreTimeUtils.timestamp(), 0); |             this.timeLeft = Math.max(endTime - CoreTimeUtils.timestamp(), 0); | ||||||
| 
 | 
 | ||||||
|             if (container) { |             if (container) { | ||||||
| @ -104,7 +109,14 @@ export class CoreTimerComponent implements OnInit, OnDestroy { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Component destroyed. |      * Toggles the time left visibility. | ||||||
|  |      */ | ||||||
|  |     toggleTimeLeftVisibility(): void { | ||||||
|  |         this.showTimeLeft = !this.showTimeLeft; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @inheritdoc | ||||||
|      */ |      */ | ||||||
|     ngOnDestroy(): void { |     ngOnDestroy(): void { | ||||||
|         clearInterval(this.timeInterval); |         clearInterval(this.timeInterval); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user