MOBILE-3153 course: Implement Course Index tour

main
Noel De Martin 2022-03-08 18:05:28 +01:00
parent c5f6b058db
commit 6d71565d6b
9 changed files with 89 additions and 1 deletions

View File

@ -1567,6 +1567,8 @@
"core.course.startdate": "moodle",
"core.course.thisweek": "format_weeks/currentsection",
"core.course.todo": "completion",
"core.course.tour_navigation_course_index_student_content": "tool_usertours",
"core.course.tour_navigation_course_index_student_title": "tool_usertours",
"core.course.useactivityonbrowser": "local_moodlemobileapp",
"core.course.viewcourse": "block_timeline",
"core.course.warningmanualcompletionmodified": "local_moodlemobileapp",

View File

@ -0,0 +1 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 206 143"><rect x=".5" y="11.017" width="180.187" height="112.617" rx="6.143" fill="#EAF6FF"/><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="6" y="11" width="170" height="113"><rect x="6.106" y="11.017" width="168.975" height="112.917" rx="6.143" fill="#EAF6FF"/></mask><g mask="url(#a)"><rect x="77.78" y="20.627" width="25.627" height="6.407" rx="3.203" fill="#86CBFF"/><rect x="28.529" y="37.444" width="124.129" height="10.411" rx="5.205" fill="#86CBFF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M18.944 46.226a1.793 1.793 0 0 1-2.689.083l-4.859-5.178a1.793 1.793 0 1 1 2.615-2.454l3.533 3.765 3.646-4.05a1.793 1.793 0 0 1 2.665 2.4l-4.75 5.277c-.052.056-.105.108-.161.157Z" fill="#86CBFF"/><rect x="28.827" y="56.309" width="92.653" height="10.238" rx="5.119" fill="#C5E6FF"/><circle cx="17.821" cy="61.172" r="6.911" fill="#C5E6FF"/><rect x="28.827" y="76.537" width="78.32" height="10.238" rx="5.119" fill="#C5E6FF"/><circle cx="17.821" cy="81.4" r="6.911" fill="#C5E6FF"/><rect x="28.827" y="96.764" width="110.569" height="10.238" rx="5.119" fill="#C5E6FF"/><circle cx="17.821" cy="101.628" r="6.911" fill="#C5E6FF"/><rect x="28.827" y="116.992" width="90.605" height="10.238" rx="5.119" fill="#C5E6FF"/><circle cx="17.821" cy="121.855" r="6.911" fill="#C5E6FF"/></g><g filter="url(#b)"><rect x="155.45" y="90.299" width="48.05" height="48.05" rx="24.025" fill="#3880FF"/><path d="M170.466 106.952a1.638 1.638 0 1 0 0 3.276 1.638 1.638 0 0 0 0-3.276ZM174.561 107.362a1.228 1.228 0 1 0 0 2.457h14.742a1.229 1.229 0 1 0 0-2.457h-14.742ZM174.561 113.095a1.229 1.229 0 1 0 0 2.457h14.742a1.228 1.228 0 1 0 0-2.457h-14.742ZM173.332 120.057c0-.679.55-1.229 1.229-1.229h14.742a1.229 1.229 0 1 1 0 2.457h-14.742c-.679 0-1.229-.55-1.229-1.228ZM168.828 114.324a1.638 1.638 0 1 1 3.275 0 1.638 1.638 0 0 1-3.275 0ZM170.466 118.419a1.638 1.638 0 1 0 0 3.275 1.638 1.638 0 0 0 0-3.275Z" fill="#fff"/></g><path d="m166.471 0-11.559 20.02h23.118L166.471 0Zm-2.002 79.282a2.002 2.002 0 1 0 4.004 0h-4.004Zm0-69.844a2.002 2.002 0 1 0 4.004 0h-4.004Zm4.004 7.551a2.002 2.002 0 1 0-4.004 0h4.004Zm-4.004 18.877a2.002 2.002 0 1 0 4.004 0h-4.004Zm4.004 7.55a2.002 2.002 0 1 0-4.004 0h4.004Zm-4.004 18.877a2.002 2.002 0 1 0 4.004 0h-4.004Zm4.004 7.55a2.002 2.002 0 1 0-4.004 0h4.004Zm-4.004-52.854v18.877h4.004V16.989h-4.004Zm0 26.427v18.877h4.004V43.416h-4.004Zm0 26.428v9.438h4.004v-9.438h-4.004Z" fill="#0056B3"/><defs><filter id="b" x="153.266" y="90.299" width="52.418" height="52.418" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="2.184"/><feGaussianBlur stdDeviation="1.092"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0.120972 0 0 0 0 0.203233 0 0 0 0 0.279167 0 0 0 0.25 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_319_9155"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_319_9155" result="shape"/></filter></defs></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -28,6 +28,7 @@ import { CoreCourseModuleInfoComponent } from './module-info/module-info';
import { CoreCourseModuleManualCompletionComponent } from './module-manual-completion/module-manual-completion';
import { CoreCourseModuleNavigationComponent } from './module-navigation/module-navigation';
import { CoreCourseModuleSummaryComponent } from './module-summary/module-summary';
import { CoreCourseCourseIndexTourComponent } from './course-index-tour/course-index-tour';
@NgModule({
declarations: [
@ -39,6 +40,7 @@ import { CoreCourseModuleSummaryComponent } from './module-summary/module-summar
CoreCourseModuleInfoComponent,
CoreCourseModuleManualCompletionComponent,
CoreCourseCourseIndexComponent,
CoreCourseCourseIndexTourComponent,
CoreCourseTagAreaComponent,
CoreCourseUnsupportedModuleComponent,
CoreCourseModuleNavigationComponent,
@ -57,6 +59,7 @@ import { CoreCourseModuleSummaryComponent } from './module-summary/module-summar
CoreCourseModuleInfoComponent,
CoreCourseModuleManualCompletionComponent,
CoreCourseCourseIndexComponent,
CoreCourseCourseIndexTourComponent,
CoreCourseTagAreaComponent,
CoreCourseUnsupportedModuleComponent,
CoreCourseModuleNavigationComponent,

View File

@ -49,7 +49,8 @@
<!-- Course Index button. -->
<ion-fab slot="fixed" core-fab vertical="bottom" horizontal="end" *ngIf="loaded && displayCourseIndex">
<ion-fab-button (click)="openCourseIndex()" [attr.aria-label]="'core.course.courseindex' | translate" color="secondary">
<ion-fab-button (click)="openCourseIndex()" (onAppear)="showCourseIndexTour()" [attr.aria-label]="'core.course.courseindex' | translate"
color="secondary" #courseIndexFab>
<ion-icon name="fas-list-ul" aria-hidden="true"></ion-icon>
<span class="sr-only">{{'core.course.courseindex' | translate }}</span>
</ion-fab-button>

View File

@ -23,6 +23,7 @@ import {
QueryList,
Type,
ElementRef,
ViewChild,
} from '@angular/core';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreDynamicComponent } from '@components/dynamic-component/dynamic-component';
@ -44,6 +45,8 @@ import { CoreBlockHelper } from '@features/block/services/block-helper';
import { CoreNavigator } from '@services/navigator';
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
import { CoreCourseViewedModulesDBRecord } from '@features/course/services/database/course';
import { CoreUserTours, CoreUserToursAlignment, CoreUserToursSide } from '@features/usertours/services/user-tours';
import { CoreCourseCourseIndexTourComponent } from '../course-index-tour/course-index-tour';
/**
* Component to display course contents using a certain format. If the format isn't found, use default one.
@ -71,6 +74,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
@Input() moduleId?: number; // The module ID to scroll to. Must be inside the initial selected section.
@ViewChildren(CoreDynamicComponent) dynamicComponents?: QueryList<CoreDynamicComponent>;
@ViewChild('courseIndexFab', { read: ElementRef }) courseIndexFab?: ElementRef<HTMLElement>;
// All the possible component classes.
courseFormatComponent?: Type<unknown>;
@ -160,6 +164,25 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
});
}
/**
* Show Course Index User Tour.
*/
async showCourseIndexTour(): Promise<void> {
const nativeButton = this.courseIndexFab?.nativeElement.shadowRoot?.children[0] as HTMLElement;
if (!nativeButton) {
return;
}
await CoreUserTours.showIfPending({
id: 'course-index',
component: CoreCourseCourseIndexTourComponent,
focus: nativeButton,
side: CoreUserToursSide.Top,
alignment: CoreUserToursAlignment.End,
});
}
/**
* Detect changes on input properties.
*/

View File

@ -0,0 +1,6 @@
<h2>{{ 'core.course.tour_navigation_course_index_student_title' | translate }}</h2>
<img src="assets/img/user-tours/course-index.svg" alt="" />
<p>{{ 'core.course.tour_navigation_course_index_student_content' | translate }}</p>
<ion-button (click)="dismiss()" expand="block">
{{ 'core.endonesteptour' | translate }}
</ion-button>

View File

@ -0,0 +1,15 @@
:host {
h2 {
margin-top: 0;
}
p {
text-align: center;
}
ion-button {
margin: 0;
}
}

View File

@ -0,0 +1,35 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component } from '@angular/core';
import { CoreUserTours } from '@features/usertours/services/user-tours';
/**
* Component showing the User Tour for the Course Index feature.
*/
@Component({
selector: 'core-course-course-index-tour',
templateUrl: 'course-index-tour.html',
styleUrls: ['course-index-tour.scss'],
})
export class CoreCourseCourseIndexTourComponent {
/**
* Dismiss the User Tour.
*/
async dismiss(): Promise<void> {
await CoreUserTours.dismiss();
}
}

View File

@ -54,6 +54,8 @@
"startdate": "Course start date",
"thisweek": "This week",
"todo": "To do",
"tour_navigation_course_index_student_content": "Browse through activities and track your progress.",
"tour_navigation_course_index_student_title": "Find your way around",
"useactivityonbrowser": "You can still use it using your device's web browser.",
"viewcourse": "View course",
"warningmanualcompletionmodified": "The manual completion of an activity was modified on the site.",