Merge pull request #3626 from NoelDeMartin/MOBILE-4288
MOBILE-4288: Filter multilang group strings
This commit is contained in:
		
						commit
						77605b87f4
					
				| @ -42,6 +42,7 @@ import { AddonCalendarEventsSource } from '@addons/calendar/classes/events-sourc | ||||
| import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager'; | ||||
| import { CoreReminders, CoreRemindersService } from '@features/reminders/services/reminders'; | ||||
| import { CoreRemindersSetReminderMenuComponent } from '@features/reminders/components/set-reminder-menu/set-reminder-menu'; | ||||
| import { CoreLang } from '@services/lang'; | ||||
| 
 | ||||
| /** | ||||
|  * Page that displays a single calendar event. | ||||
| @ -370,7 +371,7 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy { | ||||
|             const groups = await CoreGroups.getUserGroupsInCourse(courseId); | ||||
| 
 | ||||
|             const group = groups.find((group) => group.id == event.groupid); | ||||
|             this.groupName = group ? group.name : ''; | ||||
|             this.groupName = group ? await CoreLang.filterMultilang(group.name) : ''; | ||||
| 
 | ||||
|         } catch { | ||||
|             // Error getting groups, just don't show the group name.
 | ||||
|  | ||||
| @ -21,7 +21,7 @@ import { CoreSite } from '@classes/site'; | ||||
| import { makeSingleton } from '@singletons'; | ||||
| 
 | ||||
| /** | ||||
|  * Handler to support the Multilang filter. | ||||
|  * Handler to support the Multilang filter in core. | ||||
|  */ | ||||
| @Injectable({ providedIn: 'root' }) | ||||
| export class AddonFilterMultilangHandlerService extends CoreFilterDefaultHandler { | ||||
|  | ||||
| @ -19,7 +19,9 @@ import { CoreFilterDefaultHandler } from '@features/filter/services/handlers/def | ||||
| import { makeSingleton } from '@singletons'; | ||||
| 
 | ||||
| /** | ||||
|  * Handler to support the Multilang filter. | ||||
|  * Handler to support the multilang2 community filter. | ||||
|  * | ||||
|  * @see https://moodle.org/plugins/filter_multilang2
 | ||||
|  */ | ||||
| @Injectable({ providedIn: 'root' }) | ||||
| export class AddonFilterMultilang2HandlerService extends CoreFilterDefaultHandler { | ||||
|  | ||||
| @ -33,6 +33,7 @@ import { CoreError } from '@classes/errors/error'; | ||||
| import { AddonMessagesSyncEvents, AddonMessagesSyncProvider } from './messages-sync'; | ||||
| import { CoreWSError } from '@classes/errors/wserror'; | ||||
| import { AddonNotificationsPreferencesNotificationProcessorState } from '@addons/notifications/services/notifications'; | ||||
| import { MultilangString } from '@services/lang'; | ||||
| 
 | ||||
| const ROOT_CACHE_KEY = 'mmaMessages:'; | ||||
| 
 | ||||
| @ -2970,7 +2971,7 @@ export type AddonMessagesConversationMember = { | ||||
|     conversations?: { // Conversations between users.
 | ||||
|         id: number; // Conversations id.
 | ||||
|         type: number; // Conversation type: private or public.
 | ||||
|         name: string; // Multilang compatible conversation name2.
 | ||||
|         name: MultilangString; // Multilang compatible conversation name2.
 | ||||
|         timecreated: number; // The timecreated timestamp for the conversation.
 | ||||
|     }[]; | ||||
| }; | ||||
| @ -3495,7 +3496,7 @@ export type AddonMessagesGetUserContactsWSResponse = { | ||||
|     conversations?: { // Conversations between users.
 | ||||
|         id: number; // Conversations id.
 | ||||
|         type: number; // Conversation type: private or public.
 | ||||
|         name: string; // Multilang compatible conversation name2.
 | ||||
|         name: MultilangString; // Multilang compatible conversation name2.
 | ||||
|         timecreated: number; // The timecreated timestamp for the conversation.
 | ||||
|     }[]; | ||||
| }[]; | ||||
| @ -3535,7 +3536,7 @@ export type AddonMessagesGetContactRequestsWSResponse = { | ||||
|     conversations?: { // Conversations between users.
 | ||||
|         id: number; // Conversations id.
 | ||||
|         type: number; // Conversation type: private or public.
 | ||||
|         name: string; // Multilang compatible conversation name2.
 | ||||
|         name: MultilangString; // Multilang compatible conversation name2.
 | ||||
|         timecreated: number; // The timecreated timestamp for the conversation.
 | ||||
|     }[]; | ||||
| }[]; | ||||
|  | ||||
| @ -1147,10 +1147,10 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can | ||||
|         if (this.assign.teamsubmission) { | ||||
|             if (lastAttempt.submissiongroup) { | ||||
|                 // Get the name of the group.
 | ||||
|                 promises.push(CoreGroups.getActivityAllowedGroups(this.assign.cmid).then((result) => { | ||||
|                 promises.push(CoreGroups.getActivityAllowedGroups(this.assign.cmid).then(async (result) => { | ||||
|                     const group = result.groups.find((group) => group.id === lastAttempt.submissiongroup); | ||||
|                     if (group) { | ||||
|                         lastAttempt.submissiongroupname = group.name; | ||||
|                         lastAttempt.submissiongroupname = await CoreLang.filterMultilang(group.name); | ||||
|                     } | ||||
| 
 | ||||
|                     return; | ||||
|  | ||||
| @ -35,6 +35,7 @@ import { AddonModAssignSync, AddonModAssignSyncResult } from '../assign-sync'; | ||||
| import { CoreUser } from '@features/user/services/user'; | ||||
| import { CoreGradesHelper } from '@features/grades/services/grades-helper'; | ||||
| import { CoreCourses } from '@features/courses/services/courses'; | ||||
| import { multilangString } from '@services/lang'; | ||||
| 
 | ||||
| /** | ||||
|  * Handler to prefetch assigns. | ||||
| @ -355,7 +356,7 @@ export class AddonModAssignPrefetchHandlerService extends CoreCourseActivityPref | ||||
| 
 | ||||
|         // Teacher, prefetch all submissions.
 | ||||
|         if (!groupInfo.groups || groupInfo.groups.length == 0) { | ||||
|             groupInfo.groups = [{ id: 0, name: '' }]; | ||||
|             groupInfo.groups = [{ id: 0, name: multilangString() }]; | ||||
|         } | ||||
| 
 | ||||
|         const promises = groupInfo.groups.map((group) => | ||||
|  | ||||
| @ -12,6 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { multilangString } from '@services/lang'; | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreComments } from '@features/comments/services/comments'; | ||||
| import { CoreCourseActivityPrefetchHandlerBase } from '@features/course/classes/activity-prefetch-handler'; | ||||
| @ -98,7 +99,7 @@ export class AddonModDataPrefetchHandlerService extends CoreCourseActivityPrefet | ||||
| 
 | ||||
|             const groupInfo = await CoreGroups.getActivityGroupInfo(module.id, false, undefined, options.siteId); | ||||
|             if (!groupInfo.groups || groupInfo.groups.length == 0) { | ||||
|                 groupInfo.groups = [{ id: 0, name: '' }]; | ||||
|                 groupInfo.groups = [{ id: 0, name: multilangString() }]; | ||||
|             } | ||||
|             groups = groupInfo.groups || []; | ||||
| 
 | ||||
|  | ||||
| @ -12,6 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { multilangString } from '@services/lang'; | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreCourseActivityPrefetchHandlerBase } from '@features/course/classes/activity-prefetch-handler'; | ||||
| import { CoreCourseAnyModuleData, CoreCourseCommonModWSOptions } from '@features/course/services/course'; | ||||
| @ -187,7 +188,7 @@ export class AddonModFeedbackPrefetchHandlerService extends CoreCourseActivityPr | ||||
|         const promises: Promise<unknown>[] = []; | ||||
| 
 | ||||
|         if (!groupInfo.groups || groupInfo.groups.length == 0) { | ||||
|             groupInfo.groups = [{ id: 0, name: '' }]; | ||||
|             groupInfo.groups = [{ id: 0, name: multilangString() }]; | ||||
|         } | ||||
| 
 | ||||
|         groupInfo.groups.forEach((group) => { | ||||
|  | ||||
| @ -44,6 +44,7 @@ import { AddonModForumDiscussionsSwipeManager } from '../../classes/forum-discus | ||||
| import { ActivatedRoute, ActivatedRouteSnapshot } from '@angular/router'; | ||||
| import { AddonModForumDiscussionsSource } from '../../classes/forum-discussions-source'; | ||||
| import { CoreRoutedItemsManagerSourcesTracker } from '@classes/items-management/routed-items-manager-sources-tracker'; | ||||
| import { CoreLang, multilangString } from '@services/lang'; | ||||
| 
 | ||||
| type NewDiscussionData = { | ||||
|     subject: string; | ||||
| @ -190,14 +191,14 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea | ||||
|                             } | ||||
| 
 | ||||
|                             // eslint-disable-next-line promise/no-nesting
 | ||||
|                             return promise.then((forumGroups) => { | ||||
|                             return promise.then(async (forumGroups) => { | ||||
|                                 if (forumGroups.length > 0) { | ||||
|                                     this.groups = forumGroups; | ||||
|                                     this.groupIds = forumGroups.map((group) => group.id).filter((id) => id > 0); | ||||
|                                     // Do not override group id.
 | ||||
|                                     this.newDiscussion.groupId = this.newDiscussion.groupId || this.getInitialGroupId(); | ||||
|                                     this.showGroups = true; | ||||
|                                     this.calculateGroupName(); | ||||
|                                     await this.calculateGroupName(); | ||||
|                                     if (this.groupIds.length <= 1) { | ||||
|                                         this.newDiscussion.postToAllGroups = false; | ||||
|                                     } | ||||
| @ -271,7 +272,7 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea | ||||
|                             this.newDiscussion.subscribe = !!discussion.options.discussionsubscribe; | ||||
|                             this.newDiscussion.pin = !!discussion.options.discussionpinned; | ||||
|                             this.messageControl.setValue(discussion.message); | ||||
|                             this.calculateGroupName(); | ||||
|                             await this.calculateGroupName(); | ||||
| 
 | ||||
|                             // Treat offline attachments if any.
 | ||||
|                             if (typeof discussion.options.attachmentsid === 'object' && discussion.options.attachmentsid.offline) { | ||||
| @ -426,7 +427,7 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea | ||||
|                 groups.unshift({ | ||||
|                     courseid: this.courseId, | ||||
|                     id: AddonModForumProvider.ALL_PARTICIPANTS, | ||||
|                     name: Translate.instant('core.allparticipants'), | ||||
|                     name: multilangString(Translate.instant('core.allparticipants')), | ||||
|                 }); | ||||
|             } | ||||
| 
 | ||||
| @ -611,11 +612,13 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea | ||||
|     /** | ||||
|      * Calculate current group's name. | ||||
|      */ | ||||
|     calculateGroupName(): void { | ||||
|     async calculateGroupName(): Promise<void> { | ||||
|         if (this.newDiscussion.groupId <= 0) { | ||||
|             this.groupName = undefined; | ||||
|         } else { | ||||
|             this.groupName = this.groups.find(group => group.id === this.newDiscussion.groupId)?.name; | ||||
|             const groupName = this.groups.find(group => group.id === this.newDiscussion.groupId)?.name; | ||||
| 
 | ||||
|             this.groupName = groupName && await CoreLang.filterMultilang(groupName); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -48,6 +48,7 @@ import { | ||||
| import { AddonModLessonModuleHandlerService } from '../../services/handlers/module'; | ||||
| import { CoreTime } from '@singletons/time'; | ||||
| import { CoreError } from '@classes/errors/error'; | ||||
| import { CoreLang } from '@services/lang'; | ||||
| 
 | ||||
| /** | ||||
|  * Component that displays a lesson entry page. | ||||
| @ -491,7 +492,7 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo | ||||
|         // Search the name of the group if it isn't all participants.
 | ||||
|         if (groupId && this.groupInfo && this.groupInfo.groups) { | ||||
|             const group = this.groupInfo.groups.find(group => groupId == group.id); | ||||
|             this.selectedGroupName = group?.name || ''; | ||||
|             this.selectedGroupName = group ? await CoreLang.filterMultilang(group.name) : ''; | ||||
|         } | ||||
| 
 | ||||
|         // Get the overview of retakes for the group.
 | ||||
|  | ||||
| @ -55,6 +55,7 @@ import { | ||||
| } from '../../services/wiki-sync'; | ||||
| import { AddonModWikiMapModalComponent, AddonModWikiMapModalReturn } from '../map/map'; | ||||
| import { AddonModWikiSubwikiPickerComponent } from '../subwiki-picker/subwiki-picker'; | ||||
| import { CoreLang } from '@services/lang'; | ||||
| 
 | ||||
| /** | ||||
|  * Component that displays a wiki entry page. | ||||
| @ -901,7 +902,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp | ||||
|                 if (subwiki.groupid != 0 && userGroups.length > 0) { | ||||
|                     // Get groupLabel if it has groupId.
 | ||||
|                     const group = userGroups.find(group => group.id == subwiki.groupid); | ||||
|                     groupLabel = group?.name || ''; | ||||
|                     groupLabel = group ? await CoreLang.filterMultilang(group.name) : ''; | ||||
|                 } else { | ||||
|                     groupLabel = Translate.instant('addon.mod_wiki.notingroup'); | ||||
|                 } | ||||
|  | ||||
| @ -12,6 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { multilangString } from '@services/lang'; | ||||
| import { AddonModDataSyncResult } from '@addons/mod/data/services/data-sync'; | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { CoreCourseActivityPrefetchHandlerBase } from '@features/course/classes/activity-prefetch-handler'; | ||||
| @ -105,7 +106,7 @@ export class AddonModWorkshopPrefetchHandlerService extends CoreCourseActivityPr | ||||
|             if (access.canviewallsubmissions) { | ||||
|                 const groupInfo = await CoreGroups.getActivityGroupInfo(module.id, false, undefined, options.siteId); | ||||
|                 if (!groupInfo.groups || groupInfo.groups.length == 0) { | ||||
|                     groupInfo.groups = [{ id: 0, name: '' }]; | ||||
|                     groupInfo.groups = [{ id: 0, name: multilangString() }]; | ||||
|                 } | ||||
|                 groups = groupInfo.groups; | ||||
|             } | ||||
|  | ||||
| @ -13,8 +13,8 @@ | ||||
|         </ion-label> | ||||
|         <ion-select [(ngModel)]="selected" (ionChange)="selectedChange.emit(selected)" interface="action-sheet" | ||||
|             [interfaceOptions]="{header: 'core.group' | translate}"> | ||||
|             <ion-select-option *ngFor="let groupOpt of groupInfo.groups" [value]="groupOpt.id"> | ||||
|                 {{groupOpt.name}} | ||||
|             <ion-select-option *ngFor="let option of options" [value]="option.value"> | ||||
|                 {{ option.text }} | ||||
|             </ion-select-option> | ||||
|         </ion-select> | ||||
|     </ion-item> | ||||
|  | ||||
| @ -12,8 +12,18 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; | ||||
| import { | ||||
|     Component, | ||||
|     Input, | ||||
|     Output, | ||||
|     EventEmitter, | ||||
|     ChangeDetectionStrategy, | ||||
|     OnChanges, | ||||
|     SimpleChanges, | ||||
|     ChangeDetectorRef, | ||||
| } from '@angular/core'; | ||||
| import { CoreGroupInfo } from '@services/groups'; | ||||
| import { CoreLang } from '@services/lang'; | ||||
| 
 | ||||
| /** | ||||
|  * Component to display a group selector. | ||||
| @ -23,11 +33,51 @@ import { CoreGroupInfo } from '@services/groups'; | ||||
|     templateUrl: 'group-selector.html', | ||||
|     changeDetection: ChangeDetectionStrategy.OnPush, | ||||
| }) | ||||
| export class CoreGroupSelectorComponent { | ||||
| export class CoreGroupSelectorComponent implements OnChanges { | ||||
| 
 | ||||
|     @Input() groupInfo?: CoreGroupInfo; | ||||
|     @Input() multipleGroupsMessage?: string; | ||||
|     @Input() selected!: number; | ||||
|     @Output() selectedChange = new EventEmitter<number>(); | ||||
| 
 | ||||
|     options: GroupOption[] = []; | ||||
| 
 | ||||
|     constructor(protected changeDetectorRef: ChangeDetectorRef) {} | ||||
| 
 | ||||
|     /** | ||||
|      * @inheritdoc | ||||
|      */ | ||||
|     async ngOnChanges(changes: SimpleChanges): Promise<void> { | ||||
|         if ('groupInfo' in changes) { | ||||
|             this.options = await this.getOptions(); | ||||
| 
 | ||||
|             this.changeDetectorRef.markForCheck(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get options array. | ||||
|      * | ||||
|      * @returns Options. | ||||
|      */ | ||||
|     protected async getOptions(): Promise<GroupOption[]> { | ||||
|         const options = await Promise.all( | ||||
|             (this.groupInfo?.groups ?? []).map(async group => { | ||||
|                 const text = await CoreLang.filterMultilang(group.name); | ||||
| 
 | ||||
|                 return { value: group.id, text }; | ||||
|             }), | ||||
|         ); | ||||
| 
 | ||||
|         return options; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Group display info. | ||||
|  */ | ||||
| interface GroupOption { | ||||
|     value: number; | ||||
|     text: string; | ||||
| } | ||||
|  | ||||
| @ -12,11 +12,9 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { AddonFilterMultilangHandler } from '@addons/filter/multilang/services/handlers/multilang'; | ||||
| import { AddonFilterMultilang2Handler } from '@addons/filter/multilang2/services/handlers/multilang2'; | ||||
| import { Component, Input, OnInit, Type } from '@angular/core'; | ||||
| import { FormGroup } from '@angular/forms'; | ||||
| 
 | ||||
| import { CoreLang, multilangString } from '@services/lang'; | ||||
| import { AuthEmailSignupProfileField } from '@features/login/services/login-helper'; | ||||
| import { CoreUserProfileField } from '@features/user/services/user'; | ||||
| import { CoreUserProfileFieldDelegate } from '@features/user/services/user-profile-field-delegate'; | ||||
| @ -54,8 +52,7 @@ export class CoreUserProfileFieldComponent implements OnInit { | ||||
|         this.componentClass = await CoreUserProfileFieldDelegate.getComponent(this.field, this.signup); | ||||
| 
 | ||||
|         if ('param1' in this.field && this.field.param1) { | ||||
|             this.field.param1 = await AddonFilterMultilangHandler.filter(<string> this.field.param1); | ||||
|             this.field.param1 = await AddonFilterMultilang2Handler.filter(<string> this.field.param1); | ||||
|             this.field.param1 = await CoreLang.filterMultilang(multilangString(this.field.param1)); | ||||
|         } | ||||
| 
 | ||||
|         this.data.field = this.field; | ||||
|  | ||||
| @ -20,6 +20,7 @@ import { CoreError } from '@classes/errors/error'; | ||||
| import { makeSingleton, Translate } from '@singletons'; | ||||
| import { CoreWSExternalWarning } from '@services/ws'; | ||||
| import { CoreCourses } from '@features/courses/services/courses'; | ||||
| import { multilangString, MultilangString } from '@services/lang'; | ||||
| 
 | ||||
| const ROOT_CACHE_KEY = 'mmGroups:'; | ||||
| 
 | ||||
| @ -174,7 +175,7 @@ export class CoreGroupsProvider { | ||||
|             groupInfo.defaultGroupId = 0; | ||||
|         } else { | ||||
|             if (result.canaccessallgroups || groupInfo.visibleGroups) { | ||||
|                 groupInfo.groups.push({ id: 0, name: Translate.instant('core.allparticipants') }); | ||||
|                 groupInfo.groups.push({ id: 0, name: multilangString(Translate.instant('core.allparticipants')) }); | ||||
|                 groupInfo.defaultGroupId = 0; | ||||
|             } else { | ||||
|                 groupInfo.defaultGroupId = result.groups[0].id; | ||||
| @ -442,7 +443,7 @@ export const CoreGroups = makeSingleton(CoreGroupsProvider); | ||||
|  */ | ||||
| export type CoreGroup = { | ||||
|     id: number; // Group ID.
 | ||||
|     name: string; // Multilang compatible name, course unique'.
 | ||||
|     name: MultilangString; // Multilang compatible name, course unique'.
 | ||||
|     description?: string; // Group description text.
 | ||||
|     descriptionformat?: number; // Description format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
 | ||||
|     idnumber?: string; // Id number.
 | ||||
| @ -526,7 +527,7 @@ type CoreGroupGetCourseUserGroupsWSParams = { | ||||
| export type CoreGroupGetCourseUserGroupsWSResponse = { | ||||
|     groups: { | ||||
|         id: number; // Group record id.
 | ||||
|         name: string; // Multilang compatible name, course unique.
 | ||||
|         name: MultilangString; // Multilang compatible name, course unique.
 | ||||
|         description: string; // Group description text.
 | ||||
|         descriptionformat: number; // Description format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
 | ||||
|         idnumber: string; // Id number.
 | ||||
|  | ||||
| @ -24,6 +24,9 @@ import { makeSingleton, Translate, Http } from '@singletons'; | ||||
| import moment from 'moment-timezone'; | ||||
| import { CoreSite } from '../classes/site'; | ||||
| import { CorePlatform } from '@services/platform'; | ||||
| import { AddonFilterMultilangHandler } from '@addons/filter/multilang/services/handlers/multilang'; | ||||
| import { AddonFilterMultilang2Handler } from '@addons/filter/multilang2/services/handlers/multilang2'; | ||||
| import { Brand } from '@/core/utils/types'; | ||||
| 
 | ||||
| /* | ||||
|  * Service to handle language features, like changing the current language. | ||||
| @ -516,6 +519,18 @@ export class CoreLangProvider { | ||||
|         return <Record<string, string>> await observable.toPromise(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Filter a multilang string. | ||||
|      * | ||||
|      * @param text Multilang string. | ||||
|      * @returns Filtered string. | ||||
|      */ | ||||
|     async filterMultilang(text: MultilangString): Promise<string> { | ||||
|         return Promise.resolve(text as unknown as string) | ||||
|             .then(text => AddonFilterMultilangHandler.filter(text)) | ||||
|             .then(text => AddonFilterMultilang2Handler.filter(text)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Unload custom or site plugin strings, removing them from the translations table. | ||||
|      * | ||||
| @ -547,11 +562,27 @@ export class CoreLangProvider { | ||||
| 
 | ||||
| export const CoreLang = makeSingleton(CoreLangProvider); | ||||
| 
 | ||||
| /** | ||||
|  * Make a multilang string. | ||||
|  * | ||||
|  * @param text String. | ||||
|  * @returns Multilang string. | ||||
|  */ | ||||
| export function multilangString(text: string = ''): MultilangString { | ||||
|     return text as unknown as MultilangString; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Language code. E.g. 'au', 'es', etc. | ||||
|  */ | ||||
| export type CoreLangLanguage = string; | ||||
| 
 | ||||
| /** | ||||
|  * Branded type to mark multilang strings, this is useful to avoid rendering | ||||
|  * multilang strings without filtering. | ||||
|  */ | ||||
| export type MultilangString = Brand<unknown, 'multilang'>; | ||||
| 
 | ||||
| /** | ||||
|  * Language object has two leves, first per language and second per string key. | ||||
|  */ | ||||
|  | ||||
| @ -46,7 +46,6 @@ import { CoreViewerImageComponent } from '@features/viewer/components/image/imag | ||||
| import { CoreFormFields, CoreForms } from '../../singletons/form'; | ||||
| import { CoreModalLateralTransitionEnter, CoreModalLateralTransitionLeave } from '@classes/modal-lateral-transition'; | ||||
| import { CoreZoomLevel } from '@features/settings/services/settings-helper'; | ||||
| import { AddonFilterMultilangHandler } from '@addons/filter/multilang/services/handlers/multilang'; | ||||
| import { CoreSites } from '@services/sites'; | ||||
| import { NavigationStart } from '@angular/router'; | ||||
| import { filter } from 'rxjs/operators'; | ||||
| @ -58,8 +57,8 @@ import { CoreSiteError } from '@classes/errors/siteerror'; | ||||
| import { CoreUserSupport } from '@features/user/services/support'; | ||||
| import { CoreErrorInfoComponent } from '@components/error-info/error-info'; | ||||
| import { CorePlatform } from '@services/platform'; | ||||
| import { AddonFilterMultilang2Handler } from '@addons/filter/multilang2/services/handlers/multilang2'; | ||||
| import { CoreCancellablePromise } from '@classes/cancellable-promise'; | ||||
| import { CoreLang, multilangString } from '@services/lang'; | ||||
| 
 | ||||
| /* | ||||
|  * "Utils" service with helper functions for UI, DOM elements and HTML code. | ||||
| @ -1171,8 +1170,7 @@ export class CoreDomUtilsProvider { | ||||
| 
 | ||||
|         if (hasHTMLTags && !CoreSites.getCurrentSite()?.isVersionGreaterEqualThan('3.7')) { | ||||
|             // Treat multilang.
 | ||||
|             options.message = await AddonFilterMultilangHandler.filter(<string> options.message); | ||||
|             options.message = await AddonFilterMultilang2Handler.filter(<string> options.message); | ||||
|             options.message = await CoreLang.filterMultilang(multilangString(<string> options.message)); | ||||
|         } | ||||
| 
 | ||||
|         const alertId = <string> Md5.hashAsciiStr((options.header || '') + '#' + (options.message || '')); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user