Skip to content

Commit a4428b7

Browse files
committed
MOBILE-3890 course: Detect language on single activity course
1 parent 670c75f commit a4428b7

File tree

4 files changed

+97
-23
lines changed

4 files changed

+97
-23
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
@app_parallel_run_quiz @addon_mod_quiz @app @mod @mod_quiz @javascript @singleactivity @forced_language
3+
Feature: Test single activity of quiz type in app
4+
In order to view a quiz while using the mobile app
5+
As a student
6+
I need single activity of quiz type functionality to work
7+
8+
Background:
9+
Given the following "users" exist:
10+
| username | firstname | lastname |
11+
| student1 | First | Student |
12+
And the following "courses" exist:
13+
| fullname | shortname | category | format | activitytype | lang |
14+
| Single activity quiz course | C1 | 0 | singleactivity | quiz | es |
15+
And the following "course enrolments" exist:
16+
| user | course | role |
17+
| student1 | C1 | student |
18+
And the following "activities" exist:
19+
| activity | name | intro | course | idnumber | lang |
20+
| quiz | Single activity quiz | Test quiz description | C1 | quiz1 | ca |
21+
And the following "language pack" exists:
22+
| language | es | ca |
23+
24+
Scenario: Single activity quiz
25+
Given I entered the course "Single activity quiz course" as "student1" in the app
26+
Then I should find "Single activity quiz course" in the app
27+
28+
When I set "page-core-course-index core-course-image" styles to "background" "lightblue"
29+
And I set "page-core-course-index core-course-image" styles to "--core-image-visibility" "hidden"
30+
Then the UI should match the snapshot
31+
And I should find "Encara no s'han afegit preguntes" in the app
32+
33+
When I press "Participants" in the app
34+
Then I should find "Último acceso" in the app
35+
And I should find "Participantes" in the app
25.6 KB
Loading

src/core/features/course/format/singleactivity/components/singleactivity.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import { CoreCourse } from '@features/course/services/course';
2222
import type { CoreCourseModuleMainActivityComponent } from '@features/course/classes/main-activity-component';
2323
import { CoreSharedModule } from '@/core/shared.module';
2424
import { CoreCourseFormatDynamicComponent } from '@features/course/classes/base-course-format-component';
25+
import { CoreCourseForceLanguage } from '@features/course/services/course-force-language';
26+
import { CoreLang } from '@services/lang';
2527

2628
/**
2729
* Component to display single activity format. It will determine the right component to use and instantiate it.
@@ -60,12 +62,15 @@ export class CoreCourseFormatSingleActivityComponent extends CoreCourseFormatDyn
6062

6163
this.data.courseId = this.course.id;
6264
this.data.module = module;
65+
this.moduleId = module?.id;
6366

6467
if (module && !this.componentClass) {
6568
// We haven't obtained the class yet. Get it now.
6669
const component = await CoreCourseModuleDelegate.getMainComponent(this.course, module);
6770
this.componentClass = component || CoreCourseUnsupportedModuleComponent;
6871
}
72+
73+
await this.refreshLanguage();
6974
}
7075

7176
/**
@@ -93,8 +98,9 @@ export class CoreCourseFormatSingleActivityComponent extends CoreCourseFormatDyn
9398
/**
9499
* User entered the page that contains the component.
95100
*/
96-
ionViewDidEnter(): void {
101+
async ionViewDidEnter(): Promise<void> {
97102
this.dynamicComponent()?.callComponentMethod('ionViewDidEnter');
103+
await this.refreshLanguage();
98104
}
99105

100106
/**
@@ -104,4 +110,18 @@ export class CoreCourseFormatSingleActivityComponent extends CoreCourseFormatDyn
104110
this.dynamicComponent()?.callComponentMethod('ionViewDidLeave');
105111
}
106112

113+
/**
114+
* Refresh the language according to course/module forced language.
115+
*/
116+
async refreshLanguage(): Promise<void> {
117+
try {
118+
const lang =
119+
await CoreCourseForceLanguage.getForcedLanguageFromCourseOrModule(this.course, this.course?.id, this.moduleId);
120+
121+
await CoreLang.forceContextLanguage(lang);
122+
} catch {
123+
// Ignore errors.
124+
}
125+
}
126+
107127
}

src/core/features/course/services/course-force-language.ts

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ import { ActivatedRoute, NavigationEnd } from '@angular/router';
1818
import { CoreSitesReadingStrategy } from '@services/sites';
1919
import { makeSingleton, Router } from '@singletons';
2020
import {
21+
CoreCourseAnyCourseData,
2122
CoreCourses,
2223
CoreCourseSearchedData,
2324
} from '../../courses/services/courses';
2425
import { CoreNavigator } from '@services/navigator';
2526
import { filter } from 'rxjs/operators';
26-
import { CorePromiseUtils } from '@static/promise-utils';
2727
import { CoreLang } from '@services/lang';
2828
import { CoreCourse } from './course';
2929
import { CoreCourseModuleDelegate } from './module-delegate';
@@ -84,9 +84,30 @@ export class CoreCourseForceLanguageService {
8484
* @returns Language code if forced.
8585
*/
8686
protected async getForcedLanguageFromRoute(source: CoreCourseForceLanguageSource): Promise<string | undefined> {
87-
let course = CoreNavigator.getRouteParam<CoreCourseSearchedData>('course');
88-
let courseId = course?.id ?? CoreNavigator.getRouteNumberParam('courseId');
87+
const course = CoreNavigator.getRouteParam<CoreCourseSearchedData>('course');
88+
const courseId = course?.id ?? CoreNavigator.getRouteNumberParam('courseId');
8989

90+
let cmId: number | undefined;
91+
if (source === CoreCourseForceLanguageSource.MODULE) {
92+
cmId = CoreNavigator.getRouteNumberParam('cmId');
93+
}
94+
95+
return this.getForcedLanguageFromCourseOrModule(course, courseId, cmId);
96+
}
97+
98+
/**
99+
* Get forced language from course or module.
100+
*
101+
* @param course Course object.
102+
* @param courseId Course ID.
103+
* @param cmId Course module ID.
104+
* @returns Language code if forced.
105+
*/
106+
async getForcedLanguageFromCourseOrModule(
107+
course?: CoreCourseAnyCourseData,
108+
courseId?: number,
109+
cmId?: number,
110+
): Promise<string | undefined> {
90111
if (!courseId) {
91112
// Not in a course/module, empty the cache and return.
92113
this.lastNavigationCheck.courseId = 0;
@@ -97,8 +118,8 @@ export class CoreCourseForceLanguageService {
97118
return;
98119
}
99120

100-
if (source === CoreCourseForceLanguageSource.MODULE) {
101-
const modLang = await this.getModuleForcedLangFromRoute(courseId);
121+
if (cmId) {
122+
const modLang = await this.getModuleForcedLang(courseId, cmId);
102123
if (modLang) {
103124
return modLang;
104125
}
@@ -114,8 +135,8 @@ export class CoreCourseForceLanguageService {
114135
lang = course.lang;
115136
} else {
116137
try {
117-
course = await
118-
CoreCourses.getCourseByField('id', courseId, { readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE });
138+
course =
139+
await CoreCourses.getCourseByField('id', courseId, { readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE });
119140
lang = course.lang;
120141
} catch {
121142
lang = undefined;
@@ -133,26 +154,24 @@ export class CoreCourseForceLanguageService {
133154
* Get module forced language from route.
134155
*
135156
* @param courseId Course ID of the module.
157+
* @param cmId Course module ID.
136158
* @returns Module forced language if found.
137159
*/
138-
protected async getModuleForcedLangFromRoute(courseId: number): Promise<string | undefined> {
139-
const cmId = CoreNavigator.getRouteNumberParam('cmId');
160+
protected async getModuleForcedLang(courseId: number, cmId: number): Promise<string | undefined> {
140161
let lang: string | undefined = undefined;
141-
if (cmId) {
142-
if (this.lastNavigationCheck.cmId === cmId) {
143-
lang = this.lastNavigationCheck.cmLang;
144-
} else {
162+
163+
if (this.lastNavigationCheck.cmId === cmId) {
164+
lang = this.lastNavigationCheck.cmLang;
165+
} else {
166+
try {
145167
// TODO: In the future this should directly return the module language instead of checking the delegate.
146168
// See: MDL-87241
147-
const module = await CorePromiseUtils.ignoreErrors(
148-
CoreCourse.getModule(cmId, courseId, undefined, true),
149-
);
150-
151-
if (module) {
152-
lang = await CorePromiseUtils.ignoreErrors(
153-
CoreCourseModuleDelegate.getModuleForcedLang(module),
154-
);
155-
}
169+
const module = await CoreCourse.getModule(cmId, courseId, undefined, true);
170+
171+
lang = await CoreCourseModuleDelegate.getModuleForcedLang(module);
172+
} catch {
173+
lang = undefined;
174+
cmId = 0;
156175
}
157176
}
158177

0 commit comments

Comments
 (0)