forked from CIT/Vmeda.Online
		
	
						commit
						eb19e61a2d
					
				| @ -24,9 +24,7 @@ | |||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <h2>{{ 'core.name' | translate}}</h2> |                 <h2>{{ 'core.name' | translate}}</h2> | ||||||
|                 <p> |                 <p>{{ user.fullname }}</p> | ||||||
|                     <core-format-text clean="true" [text]="user.fullname"></core-format-text> |  | ||||||
|                 </p> |  | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-item-group> |         </ion-item-group> | ||||||
| 
 | 
 | ||||||
| @ -36,14 +34,12 @@ | |||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <ion-item text-wrap *ngIf="badge.issuername"> |             <ion-item text-wrap *ngIf="badge.issuername"> | ||||||
|                 <h2>{{ 'addon.badges.issuername' | translate}}</h2> |                 <h2>{{ 'addon.badges.issuername' | translate}}</h2> | ||||||
|                 <p> |                 <p>{{ badge.issuername }}</p> | ||||||
|                     <core-format-text clean="true" [text]="badge.issuername"></core-format-text> |  | ||||||
|                 </p> |  | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.issuercontact"> |             <ion-item text-wrap *ngIf="badge.issuercontact"> | ||||||
|                 <h2>{{ 'addon.badges.contact' | translate}}</h2> |                 <h2>{{ 'addon.badges.contact' | translate}}</h2> | ||||||
|                 <p><a href="mailto:{{badge.issuercontact}}" core-link auto-login="no"> |                 <p><a href="mailto:{{badge.issuercontact}}" core-link auto-login="no"> | ||||||
|                     <core-format-text [text]="badge.issuercontact"></core-format-text> |                     {{ badge.issuercontact }} | ||||||
|                 </a></p> |                 </a></p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-item-group> |         </ion-item-group> | ||||||
| @ -66,9 +62,7 @@ | |||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.description"> |             <ion-item text-wrap *ngIf="badge.description"> | ||||||
|                 <h2>{{ 'core.description' | translate}}</h2> |                 <h2>{{ 'core.description' | translate}}</h2> | ||||||
|                 <p> |                 <p>{{ badge.description }}</p> | ||||||
|                     <core-format-text clean="true" [text]="badge.description"></core-format-text> |  | ||||||
|                 </p> |  | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.imageauthorname"> |             <ion-item text-wrap *ngIf="badge.imageauthorname"> | ||||||
|                 <h2>{{ 'addon.badges.imageauthorname' | translate}}</h2> |                 <h2>{{ 'addon.badges.imageauthorname' | translate}}</h2> | ||||||
| @ -77,23 +71,23 @@ | |||||||
|             <ion-item text-wrap *ngIf="badge.imageauthoremail"> |             <ion-item text-wrap *ngIf="badge.imageauthoremail"> | ||||||
|                 <h2>{{ 'addon.badges.imageauthoremail' | translate}}</h2> |                 <h2>{{ 'addon.badges.imageauthoremail' | translate}}</h2> | ||||||
|                 <p><a href="mailto:{{badge.imageauthoremail}}" core-link auto-login="no"> |                 <p><a href="mailto:{{badge.imageauthoremail}}" core-link auto-login="no"> | ||||||
|                     <core-format-text [text]="badge.imageauthoremail"></core-format-text> |                     {{ badge.imageauthoremail }} | ||||||
|                 </a></p> |                 </a></p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.imageauthorurl"> |             <ion-item text-wrap *ngIf="badge.imageauthorurl"> | ||||||
|                 <h2>{{ 'addon.badges.imageauthorurl' | translate}}</h2> |                 <h2>{{ 'addon.badges.imageauthorurl' | translate}}</h2> | ||||||
|                 <p><a [href]="badge.imageauthorurl" core-link auto-login="no"> |                 <p><a [href]="badge.imageauthorurl" core-link auto-login="no"> | ||||||
|                     <core-format-text [text]="badge.imageauthorurl"></core-format-text> |                     {{ badge.imageauthorurl }} | ||||||
|                 </a></p> |                 </a></p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.imagecaption"> |             <ion-item text-wrap *ngIf="badge.imagecaption"> | ||||||
|                 <h2>{{ 'addon.badges.imagecaption' | translate}}</h2> |                 <h2>{{ 'addon.badges.imagecaption' | translate}}</h2> | ||||||
|                 <p><core-format-text [text]="badge.imagecaption"></core-format-text></p> |                 <p>{{ badge.imagecaption }}</p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="course.fullname"> |             <ion-item text-wrap *ngIf="course.fullname"> | ||||||
|                 <h2>{{ 'core.course' | translate}}</h2> |                 <h2>{{ 'core.course' | translate}}</h2> | ||||||
|                 <p> |                 <p> | ||||||
|                     <core-format-text [text]="course.fullname"></core-format-text> |                     <core-format-text [text]="course.fullname" contextLevel="course" [contextInstanceId]="courseId"></core-format-text> | ||||||
|                 </p> |                 </p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <!-- Criteria (not yet avalaible) --> |             <!-- Criteria (not yet avalaible) --> | ||||||
| @ -131,13 +125,13 @@ | |||||||
|             <ion-item text-wrap *ngIf="badge.endorsement.issueremail"> |             <ion-item text-wrap *ngIf="badge.endorsement.issueremail"> | ||||||
|                 <h2>{{ 'addon.badges.issueremail' | translate}}</h2> |                 <h2>{{ 'addon.badges.issueremail' | translate}}</h2> | ||||||
|                 <p><a href="mailto:{{badge.endorsement.issueremail}}" core-link auto-login="no"> |                 <p><a href="mailto:{{badge.endorsement.issueremail}}" core-link auto-login="no"> | ||||||
|                     <core-format-text [text]="badge.endorsement.issueremail"></core-format-text> |                     {{ badge.endorsement.issueremail }} | ||||||
|                 </a></p> |                 </a></p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.endorsement.issuerurl"> |             <ion-item text-wrap *ngIf="badge.endorsement.issuerurl"> | ||||||
|                 <h2>{{ 'addon.badges.issuerurl' | translate}}</h2> |                 <h2>{{ 'addon.badges.issuerurl' | translate}}</h2> | ||||||
|                 <p><a [href]="badge.endorsement.issuerurl" core-link auto-login="no"> |                 <p><a [href]="badge.endorsement.issuerurl" core-link auto-login="no"> | ||||||
|                     <core-format-text [text]="badge.endorsement.issuerurl"></core-format-text> |                     {{ badge.endorsement.issuerurl }} | ||||||
|                 </a></p> |                 </a></p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.endorsement.dateissued"> |             <ion-item text-wrap *ngIf="badge.endorsement.dateissued"> | ||||||
| @ -147,14 +141,12 @@ | |||||||
|             <ion-item text-wrap *ngIf="badge.endorsement.claimid"> |             <ion-item text-wrap *ngIf="badge.endorsement.claimid"> | ||||||
|                 <h2>{{ 'addon.badges.claimid' | translate}}</h2> |                 <h2>{{ 'addon.badges.claimid' | translate}}</h2> | ||||||
|                 <p><a [href]="badge.endorsement.claimid" core-link auto-login="no"> |                 <p><a [href]="badge.endorsement.claimid" core-link auto-login="no"> | ||||||
|                     <core-format-text [text]="badge.endorsement.claimid"></core-format-text> |                     {{ badge.endorsement.claimid }} | ||||||
|                 </a></p> |                 </a></p> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.endorsement.claimcomment"> |             <ion-item text-wrap *ngIf="badge.endorsement.claimcomment"> | ||||||
|                 <h2>{{ 'addon.badges.claimcomment' | translate}}</h2> |                 <h2>{{ 'addon.badges.claimcomment' | translate}}</h2> | ||||||
|                 <p> |                 <p>{{ badge.endorsement.claimcomment }}</p> | ||||||
|                     <core-format-text [text]="badge.endorsement.claimcomment"></core-format-text> |  | ||||||
|                 </p> |  | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-item-group> |         </ion-item-group> | ||||||
| 
 | 
 | ||||||
| @ -164,7 +156,7 @@ | |||||||
|                 <h2>{{ 'addon.badges.relatedbages' | translate}}</h2> |                 <h2>{{ 'addon.badges.relatedbages' | translate}}</h2> | ||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <ion-item text-wrap *ngFor="let relatedBadge of badge.relatedbadges"> |             <ion-item text-wrap *ngFor="let relatedBadge of badge.relatedbadges"> | ||||||
|                 <h2><core-format-text [text]="relatedBadge.name"></core-format-text></h2> |                 <h2><{{ relatedBadge.name }}</h2> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="badge.relatedbadges.length == 0"> |             <ion-item text-wrap *ngIf="badge.relatedbadges.length == 0"> | ||||||
|                 <h2>{{ 'addon.badges.norelated' | translate}}</h2> |                 <h2>{{ 'addon.badges.norelated' | translate}}</h2> | ||||||
| @ -177,7 +169,7 @@ | |||||||
|                 <h2>{{ 'addon.badges.alignment' | translate}}</h2> |                 <h2>{{ 'addon.badges.alignment' | translate}}</h2> | ||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <a ion-item text-wrap *ngFor="let alignment of badge.alignment" [href]="alignment.targeturl" core-link auto-login="no"> |             <a ion-item text-wrap *ngFor="let alignment of badge.alignment" [href]="alignment.targeturl" core-link auto-login="no"> | ||||||
|                 <h2><core-format-text [text]="alignment.targetname"></core-format-text></h2> |                 <h2>{{ alignment.targetname }}</h2> | ||||||
|             </a> |             </a> | ||||||
|             <ion-item text-wrap *ngIf="badge.alignment.length == 0"> |             <ion-item text-wrap *ngIf="badge.alignment.length == 0"> | ||||||
|                 <h2>{{ 'addon.badges.noalignment' | translate}}</h2> |                 <h2>{{ 'addon.badges.noalignment' | translate}}</h2> | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ | |||||||
|                     <ion-avatar item-start> |                     <ion-avatar item-start> | ||||||
|                         <img [src]="badge.badgeurl" [alt]="badge.name" item-start core-external-content> |                         <img [src]="badge.badgeurl" [alt]="badge.name" item-start core-external-content> | ||||||
|                     </ion-avatar> |                     </ion-avatar> | ||||||
|                     <h2><core-format-text [text]="badge.name"></core-format-text></h2> |                     <h2>{{ badge.name }}</h2> | ||||||
|                     <p>{{ badge.dateissued * 1000 | coreFormatDate :'strftimedatetimeshort' }}</p> |                     <p>{{ badge.dateissued * 1000 | coreFormatDate :'strftimedatetimeshort' }}</p> | ||||||
|                     <ion-badge item-end color="danger" *ngIf="badge.dateexpire && currentTime >= badge.dateexpire"> |                     <ion-badge item-end color="danger" *ngIf="badge.dateexpire && currentTime >= badge.dateexpire"> | ||||||
|                         {{ 'addon.badges.expired' | translate }} |                         {{ 'addon.badges.expired' | translate }} | ||||||
|  | |||||||
| @ -4,6 +4,6 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="core-loading-center"> | <core-loading [hideUntil]="loaded" class="core-loading-center"> | ||||||
|     <a ion-item text-wrap *ngFor="let entry of entries" class="item-media" detail-none [navPush]="'CoreCourseListModTypePage'" [navParams]="{title: entry.name, courseId: instanceId, modName: entry.modName}"> |     <a ion-item text-wrap *ngFor="let entry of entries" class="item-media" detail-none [navPush]="'CoreCourseListModTypePage'" [navParams]="{title: entry.name, courseId: instanceId, modName: entry.modName}"> | ||||||
|         <img item-start [src]="entry.icon" alt="" role="presentation" class="core-module-icon"> |         <img item-start [src]="entry.icon" alt="" role="presentation" class="core-module-icon"> | ||||||
|         <core-format-text [text]="entry.name"></core-format-text> |         {{ entry.name }} | ||||||
|     </a> |     </a> | ||||||
| </core-loading> | </core-loading> | ||||||
|  | |||||||
| @ -7,8 +7,8 @@ | |||||||
|             <ion-card> |             <ion-card> | ||||||
|                 <a ion-item text-wrap detail-none class="core-course-module-handler item-media" (click)="action($event, item)" [title]="item.name"> |                 <a ion-item text-wrap detail-none class="core-course-module-handler item-media" (click)="action($event, item)" [title]="item.name"> | ||||||
|                     <img item-start [src]="item.iconUrl" alt="" role="presentation" *ngIf="item.iconUrl" class="core-module-icon"> |                     <img item-start [src]="item.iconUrl" alt="" role="presentation" *ngIf="item.iconUrl" class="core-module-icon"> | ||||||
|                     <h2><core-format-text [text]="item.name"></core-format-text></h2> |                     <h2><core-format-text [text]="item.name" contextLevel="module" [contextInstanceId]="item.cmid" [courseId]="item.courseid"></core-format-text></h2> | ||||||
|                     <p><core-format-text [text]="item.coursename"></core-format-text></p> |                     <p><core-format-text [text]="item.coursename" contextLevel="course" [contextInstanceId]="item.courseid"></core-format-text></p> | ||||||
|                 </a> |                 </a> | ||||||
|             </ion-card> |             </ion-card> | ||||||
|         </div> |         </div> | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ | |||||||
| <core-loading [hideUntil]="loaded" class="core-loading-center"> | <core-loading [hideUntil]="loaded" class="core-loading-center"> | ||||||
|     <ng-container *ngIf="mainMenuBlock"> |     <ng-container *ngIf="mainMenuBlock"> | ||||||
|         <ion-item text-wrap *ngIf="mainMenuBlock.summary"> |         <ion-item text-wrap *ngIf="mainMenuBlock.summary"> | ||||||
|             <core-format-text [text]="mainMenuBlock.summary"></core-format-text> |             <core-format-text [text]="mainMenuBlock.summary" [component]="component" [componentId]="siteHomeId" contextLevel="course" [contextInstanceId]="siteHomeId"></core-format-text> | ||||||
|         </ion-item> |         </ion-item> | ||||||
| 
 | 
 | ||||||
|         <core-course-module *ngFor="let module of mainMenuBlock.modules" [module]="module" [courseId]="siteHomeId" [downloadEnabled]="downloadEnabled" [section]="mainMenuBlock"></core-course-module> |         <core-course-module *ngFor="let module of mainMenuBlock.modules" [module]="module" [courseId]="siteHomeId" [downloadEnabled]="downloadEnabled" [section]="mainMenuBlock"></core-course-module> | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ import { CoreBlockBaseComponent } from '@core/block/classes/base-block-component | |||||||
| export class AddonBlockSiteMainMenuComponent extends CoreBlockBaseComponent implements OnInit { | export class AddonBlockSiteMainMenuComponent extends CoreBlockBaseComponent implements OnInit { | ||||||
|     @Input() downloadEnabled: boolean; |     @Input() downloadEnabled: boolean; | ||||||
| 
 | 
 | ||||||
|  |     component = 'AddonBlockSiteMainMenu'; | ||||||
|     mainMenuBlock: any; |     mainMenuBlock: any; | ||||||
|     siteHomeId: number; |     siteHomeId: number; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,9 +5,9 @@ | |||||||
|     <ng-container *ngFor="let event of dayEvents.events"> |     <ng-container *ngFor="let event of dayEvents.events"> | ||||||
|         <a ion-item text-wrap detail-none class="core-course-module-handler item-media" (click)="action($event, event.url)" [title]="event.name"> |         <a ion-item text-wrap detail-none class="core-course-module-handler item-media" (click)="action($event, event.url)" [title]="event.name"> | ||||||
|             <img item-start [src]="event.iconUrl" alt="" role="presentation" *ngIf="event.iconUrl" class="core-module-icon"> |             <img item-start [src]="event.iconUrl" alt="" role="presentation" *ngIf="event.iconUrl" class="core-module-icon"> | ||||||
|             <h2><core-format-text [text]="event.name"></core-format-text></h2> |             <h2><core-format-text [text]="event.name" contextLevel="module" [contextInstanceId]="event.id" [courseId]="event.course.id"></core-format-text></h2> | ||||||
|             <p *ngIf="showCourse"> |             <p *ngIf="showCourse"> | ||||||
|                 <core-format-text [text]="event.course.fullnamedisplay"></core-format-text> |                 <core-format-text [text]="event.course.fullnamedisplay" contextLevel="course" [contextInstanceId]="event.course.id"></core-format-text> | ||||||
|             </p> |             </p> | ||||||
| 
 | 
 | ||||||
|             <button ion-button clear class="hidden-tablet" (click)="action($event, event.action.url)" [title]="event.action.name" [disabled]="!event.action.actionable" *ngIf="event.action"> |             <button ion-button clear class="hidden-tablet" (click)="action($event, event.action.url)" [title]="event.action.name" [disabled]="!event.action.actionable" *ngIf="event.action"> | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ | |||||||
|                 <ion-item text-wrap> |                 <ion-item text-wrap> | ||||||
|                     <ion-avatar core-user-avatar [user]="entry.user" item-start [courseId]="entry.courseid"></ion-avatar> |                     <ion-avatar core-user-avatar [user]="entry.user" item-start [courseId]="entry.courseid"></ion-avatar> | ||||||
|                     <h2> |                     <h2> | ||||||
|                         <core-format-text [text]="entry.subject"></core-format-text> |                         <core-format-text [text]="entry.subject" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId"></core-format-text> | ||||||
|                         <ion-note float-end padding-left text-end> |                         <ion-note float-end padding-left text-end> | ||||||
|                             {{ 'addon.blog.' + entry.publishTranslated | translate}} |                             {{ 'addon.blog.' + entry.publishTranslated | translate}} | ||||||
|                         </ion-note> |                         </ion-note> | ||||||
| @ -27,7 +27,7 @@ | |||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-card-content> |                 <ion-card-content> | ||||||
|                     <ion-item> |                     <ion-item> | ||||||
|                         <core-format-text [text]="entry.summary" [component]="this.component" [componentId]="entry.id"></core-format-text> |                         <core-format-text [text]="entry.summary" [component]="this.component" [componentId]="entry.id" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId"></core-format-text> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                     <ion-item text-wrap *ngIf="tagsEnabled && entry.tags && entry.tags.length > 0"> |                     <ion-item text-wrap *ngIf="tagsEnabled && entry.tags && entry.tags.length > 0"> | ||||||
|                         <div item-start>{{ 'core.tag.tags' | translate }}:</div> |                         <div item-start>{{ 'core.tag.tags' | translate }}:</div> | ||||||
|  | |||||||
| @ -42,6 +42,7 @@ export class AddonBlogEntriesComponent implements OnInit { | |||||||
|     protected userPageLoaded = 0; |     protected userPageLoaded = 0; | ||||||
|     protected canLoadMoreEntries = false; |     protected canLoadMoreEntries = false; | ||||||
|     protected canLoadMoreUserEntries = true; |     protected canLoadMoreUserEntries = true; | ||||||
|  |     protected siteHomeId: number; | ||||||
| 
 | 
 | ||||||
|     @ViewChild(Content) content: Content; |     @ViewChild(Content) content: Content; | ||||||
| 
 | 
 | ||||||
| @ -55,11 +56,14 @@ export class AddonBlogEntriesComponent implements OnInit { | |||||||
|     component = AddonBlogProvider.COMPONENT; |     component = AddonBlogProvider.COMPONENT; | ||||||
|     commentsEnabled: boolean; |     commentsEnabled: boolean; | ||||||
|     tagsEnabled: boolean; |     tagsEnabled: boolean; | ||||||
|  |     contextLevel: string; | ||||||
|  |     contextInstanceId: number; | ||||||
| 
 | 
 | ||||||
|     constructor(protected blogProvider: AddonBlogProvider, protected domUtils: CoreDomUtilsProvider, |     constructor(protected blogProvider: AddonBlogProvider, protected domUtils: CoreDomUtilsProvider, | ||||||
|             protected userProvider: CoreUserProvider, sitesProvider: CoreSitesProvider, protected utils: CoreUtilsProvider, |             protected userProvider: CoreUserProvider, sitesProvider: CoreSitesProvider, protected utils: CoreUtilsProvider, | ||||||
|             protected commentsProvider: CoreCommentsProvider, private tagProvider: CoreTagProvider) { |             protected commentsProvider: CoreCommentsProvider, private tagProvider: CoreTagProvider) { | ||||||
|         this.currentUserId = sitesProvider.getCurrentSiteUserId(); |         this.currentUserId = sitesProvider.getCurrentSiteUserId(); | ||||||
|  |         this.siteHomeId = sitesProvider.getCurrentSiteHomeId(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -91,6 +95,18 @@ export class AddonBlogEntriesComponent implements OnInit { | |||||||
|             this.filter['tagid'] = this.tagId; |             this.filter['tagid'] = this.tagId; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         // Calculate the context level.
 | ||||||
|  |         if (this.userId && !this.courseId && !this.cmId) { | ||||||
|  |             this.contextLevel = 'user'; | ||||||
|  |             this.contextInstanceId = this.userId; | ||||||
|  |         } else if (this.courseId && this.courseId != this.siteHomeId) { | ||||||
|  |             this.contextLevel = 'course'; | ||||||
|  |             this.contextInstanceId = this.courseId; | ||||||
|  |         } else { | ||||||
|  |             this.contextLevel = 'system'; | ||||||
|  |             this.contextInstanceId = 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         this.commentsEnabled = !this.commentsProvider.areCommentsDisabledInSite(); |         this.commentsEnabled = !this.commentsProvider.areCommentsDisabledInSite(); | ||||||
|         this.tagsEnabled = this.tagProvider.areTagsAvailableInSite(); |         this.tagsEnabled = this.tagProvider.areTagsAvailableInSite(); | ||||||
| 
 | 
 | ||||||
| @ -134,6 +150,18 @@ export class AddonBlogEntriesComponent implements OnInit { | |||||||
|                         break; |                         break; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |                 // Calculate the context. This code was inspired by calendar events, Moodle doesn't do this for blogs.
 | ||||||
|  |                 if (entry.moduleid || entry.coursemoduleid) { | ||||||
|  |                     entry.contextLevel = 'module'; | ||||||
|  |                     entry.contextInstanceId = entry.moduleid || entry.coursemoduleid; | ||||||
|  |                 } else if (entry.courseid) { | ||||||
|  |                     entry.contextLevel = 'course'; | ||||||
|  |                     entry.contextInstanceId = entry.courseid; | ||||||
|  |                 } else { | ||||||
|  |                     entry.contextLevel = 'user'; | ||||||
|  |                     entry.contextInstanceId = entry.userid; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|                 return this.userProvider.getProfile(entry.userid, entry.courseid, true).then((user) => { |                 return this.userProvider.getProfile(entry.userid, entry.courseid, true).then((user) => { | ||||||
|                     entry.user = user; |                     entry.user = user; | ||||||
|                 }).catch(() => { |                 }).catch(() => { | ||||||
| @ -245,4 +273,6 @@ export class AddonBlogEntriesComponent implements OnInit { | |||||||
| type AddonBlogPostFormatted = AddonBlogPost & { | type AddonBlogPostFormatted = AddonBlogPost & { | ||||||
|     publishTranslated?: string; // Calculated in the app. Key of the string to translate the publish state of the post.
 |     publishTranslated?: string; // Calculated in the app. Key of the string to translate the publish state of the post.
 | ||||||
|     user?: any; // Calculated in the app. Data of the user that wrote the post.
 |     user?: any; // Calculated in the app. Data of the user that wrote the post.
 | ||||||
|  |     contextLevel?: string; // Calculated in the app. The context level of the entry.
 | ||||||
|  |     contextInstanceId?: number; // Calculated in the app. The context instance id.
 | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -7,8 +7,8 @@ | |||||||
|             <a ion-item text-wrap [title]="event.name" (click)="eventClicked(event)" [class.core-split-item-selected]="event.id == eventId" class="addon-calendar-event" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]"> |             <a ion-item text-wrap [title]="event.name" (click)="eventClicked(event)" [class.core-split-item-selected]="event.id == eventId" class="addon-calendar-event" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]"> | ||||||
|                 <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start class="core-module-icon"> |                 <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start class="core-module-icon"> | ||||||
|                 <core-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> |                 <core-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> | ||||||
|                 <h2><core-format-text [text]="event.name"></core-format-text></h2> |                 <h2><core-format-text [text]="event.name" [contextLevel]="event.contextLevel" [contextInstanceId]="event.contextInstanceId"></core-format-text></h2> | ||||||
|                 <p><core-format-text [text]="event.formattedtime"></core-format-text></p> |                 <p [innerHTML]="event.formattedtime"></p> | ||||||
|                 <ion-note *ngIf="event.offline && !event.deleted" item-end> |                 <ion-note *ngIf="event.offline && !event.deleted" item-end> | ||||||
|                     <ion-icon name="time"></ion-icon> |                     <ion-icon name="time"></ion-icon> | ||||||
|                     <span text-wrap>{{ 'core.notsent' | translate }}</span> |                     <span text-wrap>{{ 'core.notsent' | translate }}</span> | ||||||
|  | |||||||
| @ -51,8 +51,8 @@ | |||||||
|                 <ion-item text-wrap [title]="event.name" (click)="gotoEvent(event.id)" [class.item-dimmed]="event.ispast" class="addon-calendar-event" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]"> |                 <ion-item text-wrap [title]="event.name" (click)="gotoEvent(event.id)" [class.item-dimmed]="event.ispast" class="addon-calendar-event" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]"> | ||||||
|                     <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start class="core-module-icon"> |                     <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start class="core-module-icon"> | ||||||
|                     <core-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> |                     <core-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> | ||||||
|                     <h2><core-format-text [text]="event.name"></core-format-text></h2> |                     <h2><core-format-text [text]="event.name" [contextLevel]="event.contextLevel" [contextInstanceId]="event.contextInstanceId"></core-format-text></h2> | ||||||
|                     <p><core-format-text [text]="event.formattedtime"></core-format-text></p> |                     <p [innerHTML]="event.formattedtime"></p> | ||||||
|                     <ion-note *ngIf="event.offline && !event.deleted" item-end> |                     <ion-note *ngIf="event.offline && !event.deleted" item-end> | ||||||
|                         <ion-icon name="time"></ion-icon> |                         <ion-icon name="time"></ion-icon> | ||||||
|                         <span text-wrap>{{ 'core.notsent' | translate }}</span> |                         <span text-wrap>{{ 'core.notsent' | translate }}</span> | ||||||
|  | |||||||
| @ -21,7 +21,6 @@ import { CoreGroupsProvider } from '@providers/groups'; | |||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreSyncProvider } from '@providers/sync'; | import { CoreSyncProvider } from '@providers/sync'; | ||||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; |  | ||||||
| import { CoreTimeUtilsProvider } from '@providers/utils/time'; | import { CoreTimeUtilsProvider } from '@providers/utils/time'; | ||||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||||
| import { CoreCoursesProvider } from '@core/courses/providers/courses'; | import { CoreCoursesProvider } from '@core/courses/providers/courses'; | ||||||
| @ -32,6 +31,7 @@ import { AddonCalendarOfflineProvider } from '../../providers/calendar-offline'; | |||||||
| import { AddonCalendarHelperProvider } from '../../providers/helper'; | import { AddonCalendarHelperProvider } from '../../providers/helper'; | ||||||
| import { AddonCalendarSyncProvider } from '../../providers/calendar-sync'; | import { AddonCalendarSyncProvider } from '../../providers/calendar-sync'; | ||||||
| import { CoreSite } from '@classes/site'; | import { CoreSite } from '@classes/site'; | ||||||
|  | import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Page that displays a form to create/edit an event. |  * Page that displays a form to create/edit an event. | ||||||
| @ -81,7 +81,6 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy { | |||||||
|             private navCtrl: NavController, |             private navCtrl: NavController, | ||||||
|             private translate: TranslateService, |             private translate: TranslateService, | ||||||
|             private domUtils: CoreDomUtilsProvider, |             private domUtils: CoreDomUtilsProvider, | ||||||
|             private textUtils: CoreTextUtilsProvider, |  | ||||||
|             private timeUtils: CoreTimeUtilsProvider, |             private timeUtils: CoreTimeUtilsProvider, | ||||||
|             private eventsProvider: CoreEventsProvider, |             private eventsProvider: CoreEventsProvider, | ||||||
|             private groupsProvider: CoreGroupsProvider, |             private groupsProvider: CoreGroupsProvider, | ||||||
| @ -94,6 +93,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy { | |||||||
|             private calendarSync: AddonCalendarSyncProvider, |             private calendarSync: AddonCalendarSyncProvider, | ||||||
|             private fb: FormBuilder, |             private fb: FormBuilder, | ||||||
|             private syncProvider: CoreSyncProvider, |             private syncProvider: CoreSyncProvider, | ||||||
|  |             private filterHelper: CoreFilterHelperProvider, | ||||||
|             @Optional() private svComponent: CoreSplitViewComponent) { |             @Optional() private svComponent: CoreSplitViewComponent) { | ||||||
| 
 | 
 | ||||||
|         this.eventId = navParams.get('eventId'); |         this.eventId = navParams.get('eventId'); | ||||||
| @ -244,7 +244,8 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy { | |||||||
|                     // Format the name of the courses.
 |                     // Format the name of the courses.
 | ||||||
|                     const subPromises = []; |                     const subPromises = []; | ||||||
|                     courses.forEach((course) => { |                     courses.forEach((course) => { | ||||||
|                         subPromises.push(this.textUtils.formatText(course.fullname).then((text) => { |                         subPromises.push(this.filterHelper.getFiltersAndFormatText(course.fullname, 'course', course.id) | ||||||
|  |                                 .then((text) => { | ||||||
|                             course.fullname = text; |                             course.fullname = text; | ||||||
|                         }).catch(() => { |                         }).catch(() => { | ||||||
|                             // Ignore errors.
 |                             // Ignore errors.
 | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
|         <ion-title> |         <ion-title> | ||||||
|             <img *ngIf="event && event.moduleIcon" src="{{event.moduleIcon}}" alt="" role="presentation" class="core-module-icon"> |             <img *ngIf="event && event.moduleIcon" src="{{event.moduleIcon}}" alt="" role="presentation" class="core-module-icon"> | ||||||
|             <core-icon *ngIf="event && event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> |             <core-icon *ngIf="event && event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> | ||||||
|             <core-format-text *ngIf="event" [text]="event.name"></core-format-text> |             <core-format-text *ngIf="event" [text]="event.name" [contextLevel]="event.contextLevel" [contextInstanceId]="event.contextInstanceId"></core-format-text> | ||||||
|         </ion-title> |         </ion-title> | ||||||
|         <ion-buttons end> |         <ion-buttons end> | ||||||
|             <!-- The context menu will be added in here. --> |             <!-- The context menu will be added in here. --> | ||||||
| @ -34,14 +34,14 @@ | |||||||
|                     <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start alt="" role="presentation" class="core-module-icon"> |                     <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start alt="" role="presentation" class="core-module-icon"> | ||||||
|                     <core-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> |                     <core-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> | ||||||
|                     <h2>{{ 'addon.calendar.eventname' | translate }}</h2> |                     <h2>{{ 'addon.calendar.eventname' | translate }}</h2> | ||||||
|                     <p><core-format-text [text]="event.name"></core-format-text></p> |                     <p><core-format-text [text]="event.name" [contextLevel]="event.contextLevel" [contextInstanceId]="event.contextInstanceId"></core-format-text></p> | ||||||
|                     <ion-note item-end *ngIf="event.deleted"> |                     <ion-note item-end *ngIf="event.deleted"> | ||||||
|                         <ion-icon name="trash"></ion-icon> {{ 'core.deletedoffline' | translate }} |                         <ion-icon name="trash"></ion-icon> {{ 'core.deletedoffline' | translate }} | ||||||
|                     </ion-note> |                     </ion-note> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item> |                 <ion-item> | ||||||
|                     <h2>{{ 'addon.calendar.when' | translate }}</h2> |                     <h2>{{ 'addon.calendar.when' | translate }}</h2> | ||||||
|                     <p><core-format-text [text]="event.formattedtime"></core-format-text></p> |                     <p [innerHTML]="event.formattedtime"></p> | ||||||
|                     <ion-note item-end *ngIf="!isSplitViewOn && event.deleted"> |                     <ion-note item-end *ngIf="!isSplitViewOn && event.deleted"> | ||||||
|                         <ion-icon name="trash"></ion-icon> {{ 'core.deletedoffline' | translate }} |                         <ion-icon name="trash"></ion-icon> {{ 'core.deletedoffline' | translate }} | ||||||
|                     </ion-note> |                     </ion-note> | ||||||
| @ -52,7 +52,7 @@ | |||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <a ion-item text-wrap *ngIf="courseName" [href]="courseUrl" core-link capture="true"> |                 <a ion-item text-wrap *ngIf="courseName" [href]="courseUrl" core-link capture="true"> | ||||||
|                     <h2>{{ 'core.course' | translate}}</h2> |                     <h2>{{ 'core.course' | translate}}</h2> | ||||||
|                     <p><core-format-text [text]="courseName"></core-format-text></p> |                     <p><core-format-text [text]="courseName" contextLevel="course" [contextInstanceId]="courseId"></core-format-text></p> | ||||||
|                 </a> |                 </a> | ||||||
|                 <ion-item text-wrap *ngIf="groupName"> |                 <ion-item text-wrap *ngIf="groupName"> | ||||||
|                     <h2>{{ 'core.group' | translate}}</h2> |                     <h2>{{ 'core.group' | translate}}</h2> | ||||||
| @ -60,19 +60,19 @@ | |||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <a ion-item text-wrap *ngIf="categoryPath"> |                 <a ion-item text-wrap *ngIf="categoryPath"> | ||||||
|                     <h2>{{ 'core.category' | translate}}</h2> |                     <h2>{{ 'core.category' | translate}}</h2> | ||||||
|                     <p><core-format-text [text]="categoryPath"></core-format-text></p> |                     <p><core-format-text [text]="categoryPath" contextLevel="category" [contextInstanceId]="event.category.id"></core-format-text></p> | ||||||
|                 </a> |                 </a> | ||||||
|                 <ion-item text-wrap *ngIf="event.description"> |                 <ion-item text-wrap *ngIf="event.description"> | ||||||
|                     <h2>{{ 'core.description' | translate}}</h2> |                     <h2>{{ 'core.description' | translate}}</h2> | ||||||
|                     <p> |                     <p> | ||||||
|                         <core-format-text [text]="event.description"></core-format-text> |                         <core-format-text [text]="event.description" [contextLevel]="event.contextLevel" [contextInstanceId]="event.contextInstanceId"></core-format-text> | ||||||
|                     </p> |                     </p> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item text-wrap *ngIf="event.location"> |                 <ion-item text-wrap *ngIf="event.location"> | ||||||
|                     <h2>{{ 'core.location' | translate}}</h2> |                     <h2>{{ 'core.location' | translate}}</h2> | ||||||
|                     <p> |                     <p> | ||||||
|                         <a [href]="event.encodedLocation" core-link auto-login="no"> |                         <a [href]="event.encodedLocation" core-link auto-login="no"> | ||||||
|                             <core-format-text [text]="event.location"></core-format-text> |                             <core-format-text [text]="event.location" [contextLevel]="event.contextLevel" [contextInstanceId]="event.contextInstanceId"></core-format-text> | ||||||
|                         </a> |                         </a> | ||||||
|                     </p> |                     </p> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|  | |||||||
| @ -57,6 +57,7 @@ export class AddonCalendarEventPage implements OnDestroy { | |||||||
|     notificationMax: string; |     notificationMax: string; | ||||||
|     notificationTimeText: string; |     notificationTimeText: string; | ||||||
|     event: any = {}; |     event: any = {}; | ||||||
|  |     courseId: number; | ||||||
|     courseName: string; |     courseName: string; | ||||||
|     groupName: string; |     groupName: string; | ||||||
|     courseUrl = ''; |     courseUrl = ''; | ||||||
| @ -250,11 +251,13 @@ export class AddonCalendarEventPage implements OnDestroy { | |||||||
| 
 | 
 | ||||||
|             // If the event belongs to a course, get the course name and the URL to view it.
 |             // If the event belongs to a course, get the course name and the URL to view it.
 | ||||||
|             if (canGetById && event.course && event.course.id != this.siteHomeId) { |             if (canGetById && event.course && event.course.id != this.siteHomeId) { | ||||||
|  |                 this.courseId = event.course.id; | ||||||
|                 this.courseName = event.course.fullname; |                 this.courseName = event.course.fullname; | ||||||
|                 this.courseUrl = event.course.viewurl; |                 this.courseUrl = event.course.viewurl; | ||||||
|             } else if (event.courseid && event.courseid != this.siteHomeId) { |             } else if (event.courseid && event.courseid != this.siteHomeId) { | ||||||
|                 // Retrieve the course.
 |                 // Retrieve the course.
 | ||||||
|                 promises.push(this.coursesProvider.getUserCourse(event.courseid, true).then((course) => { |                 promises.push(this.coursesProvider.getUserCourse(event.courseid, true).then((course) => { | ||||||
|  |                     this.courseId = course.id; | ||||||
|                     this.courseName = course.fullname; |                     this.courseName = course.fullname; | ||||||
|                     this.courseUrl = currentSite ? this.textUtils.concatenatePaths(currentSite.siteUrl, |                     this.courseUrl = currentSite ? this.textUtils.concatenatePaths(currentSite.siteUrl, | ||||||
|                             '/course/view.php?id=' + event.courseid) : ''; |                             '/course/view.php?id=' + event.courseid) : ''; | ||||||
|  | |||||||
| @ -35,7 +35,7 @@ | |||||||
|                     <a ion-item text-wrap [title]="event.name" (click)="gotoEvent(event.id)" [class.core-split-item-selected]="event.id == eventId" class="addon-calendar-event" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]"> |                     <a ion-item text-wrap [title]="event.name" (click)="gotoEvent(event.id)" [class.core-split-item-selected]="event.id == eventId" class="addon-calendar-event" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]"> | ||||||
|                         <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start class="core-module-icon"> |                         <img *ngIf="event.moduleIcon" src="{{event.moduleIcon}}" item-start class="core-module-icon"> | ||||||
|                         <core-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> |                         <core-icon *ngIf="event.eventIcon && !event.moduleIcon" [name]="event.eventIcon" item-start></core-icon> | ||||||
|                         <h2><core-format-text [text]="event.name"></core-format-text></h2> |                         <h2><core-format-text [text]="event.name" [contextLevel]="event.contextLevel" [contextInstanceId]="event.contextInstanceId"></core-format-text></h2> | ||||||
|                         <p> |                         <p> | ||||||
|                             {{ event.timestart * 1000 | coreFormatDate: "strftimetime" }} |                             {{ event.timestart * 1000 | coreFormatDate: "strftimetime" }} | ||||||
|                             <span *ngIf="event.timeduration && event.endsSameDay"> - {{ (event.timestart + event.timeduration) * 1000 | coreFormatDate: "strftimetime" }}</span> |                             <span *ngIf="event.timeduration && event.endsSameDay"> - {{ (event.timestart + event.timeduration) * 1000 | coreFormatDate: "strftimetime" }}</span> | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ import { Injectable } from '@angular/core'; | |||||||
| import { CoreLoggerProvider } from '@providers/logger'; | import { CoreLoggerProvider } from '@providers/logger'; | ||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreCourseProvider } from '@core/course/providers/course'; | import { CoreCourseProvider } from '@core/course/providers/course'; | ||||||
| import { AddonCalendarProvider, AddonCalendarCalendarEvent } from './calendar'; | import { AddonCalendarProvider } from './calendar'; | ||||||
| import { CoreConstants } from '@core/constants'; | import { CoreConstants } from '@core/constants'; | ||||||
| import { CoreConfigProvider } from '@providers/config'; | import { CoreConfigProvider } from '@providers/config'; | ||||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||||
| @ -130,7 +130,7 @@ export class AddonCalendarHelperProvider { | |||||||
|      * |      * | ||||||
|      * @param e Event to format. |      * @param e Event to format. | ||||||
|      */ |      */ | ||||||
|     formatEventData(e: AddonCalendarCalendarEvent): void { |     formatEventData(e: any): void { | ||||||
|         e.eventIcon = this.EVENTICONS[e.eventtype] || ''; |         e.eventIcon = this.EVENTICONS[e.eventtype] || ''; | ||||||
|         if (!e.eventIcon) { |         if (!e.eventIcon) { | ||||||
|             e.eventIcon = this.courseProvider.getModuleIconSrc(e.modulename); |             e.eventIcon = this.courseProvider.getModuleIconSrc(e.modulename); | ||||||
| @ -139,6 +139,21 @@ export class AddonCalendarHelperProvider { | |||||||
| 
 | 
 | ||||||
|         e.formattedType = this.calendarProvider.getEventType(e); |         e.formattedType = this.calendarProvider.getEventType(e); | ||||||
| 
 | 
 | ||||||
|  |         // Calculate context.
 | ||||||
|  |         const categoryId = e.category ? e.category.id : e.categoryid, | ||||||
|  |             courseId = e.course ? e.course.id : e.courseid; | ||||||
|  | 
 | ||||||
|  |         if (categoryId > 0) { | ||||||
|  |             e.contextLevel = 'category'; | ||||||
|  |             e.contextInstanceId = categoryId; | ||||||
|  |         } else if (courseId > 0) { | ||||||
|  |             e.contextLevel = 'course'; | ||||||
|  |             e.contextInstanceId = courseId; | ||||||
|  |         } else { | ||||||
|  |             e.contextLevel = 'user'; | ||||||
|  |             e.contextInstanceId = e.userid; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (typeof e.duration != 'undefined') { |         if (typeof e.duration != 'undefined') { | ||||||
|             // It's an offline event, add some calculated data.
 |             // It's an offline event, add some calculated data.
 | ||||||
|             e.format = 1; |             e.format = 1; | ||||||
|  | |||||||
| @ -30,7 +30,7 @@ | |||||||
|         <ion-card *ngIf="user"> |         <ion-card *ngIf="user"> | ||||||
|              <ion-item text-wrap> |              <ion-item text-wrap> | ||||||
|                 <ion-avatar core-user-avatar [user]="user" item-start></ion-avatar> |                 <ion-avatar core-user-avatar [user]="user" item-start></ion-avatar> | ||||||
|                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |                 <h2>{{ user.fullname }}</h2> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-card> |         </ion-card> | ||||||
|         <core-empty-box *ngIf="competencies && competencies.statistics.competencycount == 0" icon="ribbon" message="{{ 'addon.competency.nocompetenciesincourse' | translate }}"></core-empty-box> |         <core-empty-box *ngIf="competencies && competencies.statistics.competencycount == 0" icon="ribbon" message="{{ 'addon.competency.nocompetenciesincourse' | translate }}"></core-empty-box> | ||||||
| @ -43,7 +43,7 @@ | |||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item text-wrap> |                 <ion-item text-wrap> | ||||||
|                     <p *ngIf="competency.competency.description"> |                     <p *ngIf="competency.competency.description"> | ||||||
|                         <core-format-text [text]=" competency.competency.description "></core-format-text> |                         <core-format-text [text]="competency.competency.description" contextLevel="course" [contextInstanceId]="courseId"></core-format-text> | ||||||
|                     </p> |                     </p> | ||||||
|                     <div> |                     <div> | ||||||
|                         <strong>{{ 'addon.competency.path' | translate }}</strong> |                         <strong>{{ 'addon.competency.path' | translate }}</strong> | ||||||
| @ -59,9 +59,7 @@ | |||||||
|                     <div *ngIf="competencies.statistics.canmanagecoursecompetencies"> |                     <div *ngIf="competencies.statistics.canmanagecoursecompetencies"> | ||||||
|                         <strong>{{ 'addon.competency.uponcoursecompletion' | translate }}</strong> |                         <strong>{{ 'addon.competency.uponcoursecompletion' | translate }}</strong> | ||||||
|                          <ng-container *ngFor="let ruleoutcome of competency.ruleoutcomeoptions"> |                          <ng-container *ngFor="let ruleoutcome of competency.ruleoutcomeoptions"> | ||||||
|                             <span *ngIf="ruleoutcome.selected"> |                             <span *ngIf="ruleoutcome.selected">{{ ruleoutcome.text }}</span> | ||||||
|                                 <core-format-text [text]="ruleoutcome.text"></core-format-text> |  | ||||||
|                             </span> |  | ||||||
|                         </ng-container> |                         </ng-container> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div> |                     <div> | ||||||
| @ -71,7 +69,7 @@ | |||||||
|                         </p> |                         </p> | ||||||
|                         <a ion-item text-wrap *ngFor="let activity of competency.coursemodules" [href]="activity.url" [title]="activity.name" core-link capture="true" class="core-course-module-handler item-media"> |                         <a ion-item text-wrap *ngFor="let activity of competency.coursemodules" [href]="activity.url" [title]="activity.name" core-link capture="true" class="core-course-module-handler item-media"> | ||||||
|                             <img item-start [src]="activity.iconurl" core-external-content alt="" role="presentation" *ngIf="activity.iconurl" class="core-module-icon"> |                             <img item-start [src]="activity.iconurl" core-external-content alt="" role="presentation" *ngIf="activity.iconurl" class="core-module-icon"> | ||||||
|                             <core-format-text [text]="activity.name"></core-format-text> |                             <core-format-text [text]="activity.name" contextLevel="module" [contextInstanceId]="activity.id" [courseId]="courseId"></core-format-text> | ||||||
|                         </a> |                         </a> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div *ngIf="competency.plans"> |                     <div *ngIf="competency.plans"> | ||||||
| @ -80,7 +78,7 @@ | |||||||
|                             {{ 'addon.competency.nouserplanswithcompetency' | translate }} |                             {{ 'addon.competency.nouserplanswithcompetency' | translate }} | ||||||
|                         </p> |                         </p> | ||||||
|                         <a ion-item text-wrap *ngFor="let plan of competency.plans" [href]="plan.url" [title]="plan.name" core-link capture="true"> |                         <a ion-item text-wrap *ngFor="let plan of competency.plans" [href]="plan.url" [title]="plan.name" core-link capture="true"> | ||||||
|                             <core-format-text [text]="plan.name"></core-format-text> |                             <core-format-text [text]="plan.name" contextLevel="user" [contextInstanceId]="plan.userid"></core-format-text> | ||||||
|                         </a> |                         </a> | ||||||
|                     </div> |                     </div> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|  | |||||||
| @ -86,7 +86,11 @@ export class AddonCompetencyCourseComponent { | |||||||
|      * @param competencyId |      * @param competencyId | ||||||
|      */ |      */ | ||||||
|     openCompetencySummary(competencyId: number): void { |     openCompetencySummary(competencyId: number): void { | ||||||
|         this.navCtrl.push('AddonCompetencyCompetencySummaryPage', {competencyId}); |         this.navCtrl.push('AddonCompetencyCompetencySummaryPage', { | ||||||
|  |             competencyId, | ||||||
|  |             contextLevel: 'course', | ||||||
|  |             contextInstanceId: this.courseId | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -11,13 +11,13 @@ | |||||||
|         <ion-card *ngIf="user"> |         <ion-card *ngIf="user"> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <ion-avatar core-user-avatar [user]="user" item-start></ion-avatar> |                 <ion-avatar core-user-avatar [user]="user" item-start></ion-avatar> | ||||||
|                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |                 <h2>{{ user.fullname }}</h2> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ion-card> |         </ion-card> | ||||||
| 
 | 
 | ||||||
|         <ion-card *ngIf="competency"> |         <ion-card *ngIf="competency"> | ||||||
|             <ion-item text-wrap *ngIf="competency.competency.competency.description"> |             <ion-item text-wrap *ngIf="competency.competency.competency.description"> | ||||||
|                 <core-format-text [text]="competency.competency.competency.description"></core-format-text> |                 <core-format-text [text]="competency.competency.competency.description" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId"></core-format-text> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <strong>{{ 'addon.competency.path' | translate }}</strong> |                 <strong>{{ 'addon.competency.path' | translate }}</strong> | ||||||
| @ -48,7 +48,7 @@ | |||||||
|                 </p> |                 </p> | ||||||
|                 <a ion-item text-wrap *ngFor="let activity of coursemodules" [href]="activity.url" [title]="activity.name" core-link capture="true"> |                 <a ion-item text-wrap *ngFor="let activity of coursemodules" [href]="activity.url" [title]="activity.name" core-link capture="true"> | ||||||
|                     <img item-start core-external-content [src]="activity.iconurl" alt="" role="presentation" *ngIf="activity.iconurl" class="core-module-icon"> |                     <img item-start core-external-content [src]="activity.iconurl" alt="" role="presentation" *ngIf="activity.iconurl" class="core-module-icon"> | ||||||
|                     <core-format-text [text]="activity.name"></core-format-text> |                     <core-format-text [text]="activity.name" contextLevel="module" [contextInstanceId]="activity.id" [courseId]="courseId"></core-format-text> | ||||||
|                 </a> |                 </a> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap *ngIf="userCompetency.status"> |             <ion-item text-wrap *ngIf="userCompetency.status"> | ||||||
| @ -84,7 +84,7 @@ | |||||||
|                 <ion-item text-wrap> |                 <ion-item text-wrap> | ||||||
|                     <p><ion-badge color="dark">{{ evidence.gradename }}</ion-badge></p> |                     <p><ion-badge color="dark">{{ evidence.gradename }}</ion-badge></p> | ||||||
|                     <p margin-top *ngIf="evidence.description">{{ evidence.description }}</p> |                     <p margin-top *ngIf="evidence.description">{{ evidence.description }}</p> | ||||||
|                     <blockquote *ngIf="evidence.note"><core-format-text [text]="evidence.note"></core-format-text></blockquote> |                     <blockquote *ngIf="evidence.note">{{ evidence.note }}</blockquote> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|             </ion-card> |             </ion-card> | ||||||
|         </div> |         </div> | ||||||
|  | |||||||
| @ -46,6 +46,8 @@ export class AddonCompetencyCompetencyPage { | |||||||
|     user: CoreUserSummary; |     user: CoreUserSummary; | ||||||
|     competency: AddonCompetencyUserCompetencySummary; |     competency: AddonCompetencyUserCompetencySummary; | ||||||
|     userCompetency: AddonCompetencyUserCompetencyPlan | AddonCompetencyUserCompetency | AddonCompetencyUserCompetencyCourse; |     userCompetency: AddonCompetencyUserCompetencyPlan | AddonCompetencyUserCompetency | AddonCompetencyUserCompetencyCourse; | ||||||
|  |     contextLevel: string; | ||||||
|  |     contextInstanceId: number; | ||||||
| 
 | 
 | ||||||
|     constructor(private navCtrl: NavController, navParams: NavParams, private translate: TranslateService, |     constructor(private navCtrl: NavController, navParams: NavParams, private translate: TranslateService, | ||||||
|             private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider, |             private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider, | ||||||
| @ -99,6 +101,15 @@ export class AddonCompetencyCompetencyPage { | |||||||
| 
 | 
 | ||||||
|         return promise.then((competency) => { |         return promise.then((competency) => { | ||||||
| 
 | 
 | ||||||
|  |             // Calculate the context.
 | ||||||
|  |             if (this.courseId) { | ||||||
|  |                 this.contextLevel = 'course'; | ||||||
|  |                 this.contextInstanceId = this.courseId; | ||||||
|  |             } else { | ||||||
|  |                 this.contextLevel = 'user'; | ||||||
|  |                 this.contextInstanceId = this.userId || competency.usercompetencysummary.user.id; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             this.competency = competency.usercompetencysummary; |             this.competency = competency.usercompetencysummary; | ||||||
|             this.userCompetency = this.competency.usercompetencyplan || this.competency.usercompetency; |             this.userCompetency = this.competency.usercompetencyplan || this.competency.usercompetency; | ||||||
| 
 | 
 | ||||||
| @ -155,6 +166,10 @@ export class AddonCompetencyCompetencyPage { | |||||||
|     openCompetencySummary(competencyId: number): void { |     openCompetencySummary(competencyId: number): void { | ||||||
|         // Decide which navCtrl to use. If this page is inside a split view, use the split view's master nav.
 |         // Decide which navCtrl to use. If this page is inside a split view, use the split view's master nav.
 | ||||||
|         const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl; |         const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl; | ||||||
|         navCtrl.push('AddonCompetencyCompetencySummaryPage', {competencyId}); |         navCtrl.push('AddonCompetencyCompetencySummaryPage', { | ||||||
|  |             competencyId, | ||||||
|  |             contextLevel: this.contextLevel, | ||||||
|  |             contextInstanceId: this.contextInstanceId | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ | |||||||
|     <core-loading [hideUntil]="competencyLoaded"> |     <core-loading [hideUntil]="competencyLoaded"> | ||||||
|         <ion-card *ngIf="competency"> |         <ion-card *ngIf="competency"> | ||||||
|             <ion-item text-wrap *ngIf="competency.competency.description"> |             <ion-item text-wrap *ngIf="competency.competency.description"> | ||||||
|                 <core-format-text [text]="competency.competency.description"></core-format-text> |                 <core-format-text [text]="competency.competency.description" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId"></core-format-text> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <strong>{{ 'addon.competency.path' | translate }}</strong> |                 <strong>{{ 'addon.competency.path' | translate }}</strong> | ||||||
|  | |||||||
| @ -30,10 +30,14 @@ export class AddonCompetencyCompetencySummaryPage { | |||||||
|     competencyLoaded = false; |     competencyLoaded = false; | ||||||
|     competencyId: number; |     competencyId: number; | ||||||
|     competency: AddonCompetencySummary; |     competency: AddonCompetencySummary; | ||||||
|  |     contextLevel: string; | ||||||
|  |     contextInstanceId: number; | ||||||
| 
 | 
 | ||||||
|     constructor(private navCtrl: NavController, navParams: NavParams, private domUtils: CoreDomUtilsProvider, |     constructor(private navCtrl: NavController, navParams: NavParams, private domUtils: CoreDomUtilsProvider, | ||||||
|             @Optional() private svComponent: CoreSplitViewComponent, private competencyProvider: AddonCompetencyProvider) { |             @Optional() private svComponent: CoreSplitViewComponent, private competencyProvider: AddonCompetencyProvider) { | ||||||
|         this.competencyId = navParams.get('competencyId'); |         this.competencyId = navParams.get('competencyId'); | ||||||
|  |         this.contextLevel = navParams.get('contextLevel'); | ||||||
|  |         this.contextInstanceId = navParams.get('contextInstanceId'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -57,8 +61,14 @@ export class AddonCompetencyCompetencySummaryPage { | |||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     protected fetchCompetency(): Promise<void> { |     protected fetchCompetency(): Promise<void> { | ||||||
|         return this.competencyProvider.getCompetencySummary(this.competencyId).then((competency) => { |         return this.competencyProvider.getCompetencySummary(this.competencyId).then((result) => { | ||||||
|             this.competency = competency; |             if (!this.contextLevel || typeof this.contextInstanceId == 'undefined') { | ||||||
|  |                 // Context not specified, use user context.
 | ||||||
|  |                 this.contextLevel = 'user'; | ||||||
|  |                 this.contextInstanceId = result.usercompetency.userid; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             this.competency = result.competency; | ||||||
|         }).catch((message) => { |         }).catch((message) => { | ||||||
|             this.domUtils.showErrorModalDefault(message, 'Error getting competency summary data.'); |             this.domUtils.showErrorModalDefault(message, 'Error getting competency summary data.'); | ||||||
|         }); |         }); | ||||||
| @ -85,6 +95,10 @@ export class AddonCompetencyCompetencySummaryPage { | |||||||
|     openCompetencySummary(competencyId: number): void { |     openCompetencySummary(competencyId: number): void { | ||||||
|         // Decide which navCtrl to use. If this page is inside a split view, use the split view's master nav.
 |         // Decide which navCtrl to use. If this page is inside a split view, use the split view's master nav.
 | ||||||
|         const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl; |         const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl; | ||||||
|         navCtrl.push('AddonCompetencyCompetencySummaryPage', {competencyId}); |         navCtrl.push('AddonCompetencyCompetencySummaryPage', { | ||||||
|  |             competencyId, | ||||||
|  |             contextLevel: this.contextLevel, | ||||||
|  |             contextInstanceId: this.contextInstanceId | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,13 +11,13 @@ | |||||||
|         <ion-card *ngIf="user"> |         <ion-card *ngIf="user"> | ||||||
|             <ion-item text-wrap> |             <ion-item text-wrap> | ||||||
|                 <ion-avatar core-user-avatar [user]="user" item-start></ion-avatar> |                 <ion-avatar core-user-avatar [user]="user" item-start></ion-avatar> | ||||||
|                 <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |                 <h2>{{ user.fullname }}</h2> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|        </ion-card> |        </ion-card> | ||||||
|         <ion-card *ngIf="plan"> |         <ion-card *ngIf="plan"> | ||||||
|             <ion-list> |             <ion-list> | ||||||
|                 <ion-item text-wrap *ngIf="plan.plan.description"> |                 <ion-item text-wrap *ngIf="plan.plan.description"> | ||||||
|                     <core-format-text [text]="plan.plan.description"></core-format-text> |                     <core-format-text [text]="plan.plan.description" contextLevel="user" [contextInstanceId]="plan.plan.userid"></core-format-text> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item text-wrap> |                 <ion-item text-wrap> | ||||||
|                     <strong>{{ 'addon.competency.status' | translate }}</strong>: |                     <strong>{{ 'addon.competency.status' | translate }}</strong>: | ||||||
|  | |||||||
| @ -299,7 +299,7 @@ export class AddonCompetencyProvider { | |||||||
|      * @return Promise to be resolved when the competency summary is retrieved. |      * @return Promise to be resolved when the competency summary is retrieved. | ||||||
|      */ |      */ | ||||||
|     getCompetencySummary(competencyId: number, userId?: number, siteId?: string, ignoreCache?: boolean) |     getCompetencySummary(competencyId: number, userId?: number, siteId?: string, ignoreCache?: boolean) | ||||||
|             : Promise<AddonCompetencySummary> { |             : Promise<AddonCompetencyUserCompetencySummary> { | ||||||
| 
 | 
 | ||||||
|         return this.sitesProvider.getSite(siteId).then((site) => { |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             userId = userId || site.getUserId(); |             userId = userId || site.getUserId(); | ||||||
| @ -324,7 +324,7 @@ export class AddonCompetencyProvider { | |||||||
|                     .then((response: AddonCompetencyUserCompetencySummary): any => { |                     .then((response: AddonCompetencyUserCompetencySummary): any => { | ||||||
| 
 | 
 | ||||||
|                 if (response.competency) { |                 if (response.competency) { | ||||||
|                     return response.competency; |                     return response; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 return Promise.reject(null); |                 return Promise.reject(null); | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/co | |||||||
| import { CoreCourseProvider } from '@core/course/providers/course'; | import { CoreCourseProvider } from '@core/course/providers/course'; | ||||||
| import { AddonCompetencyCourseComponent } from '../components/course/course'; | import { AddonCompetencyCourseComponent } from '../components/course/course'; | ||||||
| import { AddonCompetencyProvider } from '../providers/competency'; | import { AddonCompetencyProvider } from '../providers/competency'; | ||||||
|  | import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Course nav handler. |  * Course nav handler. | ||||||
| @ -26,7 +27,7 @@ export class AddonCompetencyCourseOptionHandler implements CoreCourseOptionsHand | |||||||
|     name = 'AddonCompetency'; |     name = 'AddonCompetency'; | ||||||
|     priority = 300; |     priority = 300; | ||||||
| 
 | 
 | ||||||
|     constructor(private competencyProvider: AddonCompetencyProvider) {} |     constructor(private competencyProvider: AddonCompetencyProvider, protected filterHelper: CoreFilterHelperProvider) {} | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Whether or not the handler is enabled ona site level. |      * Whether or not the handler is enabled ona site level. | ||||||
| @ -110,6 +111,18 @@ export class AddonCompetencyCourseOptionHandler implements CoreCourseOptionsHand | |||||||
| 
 | 
 | ||||||
|                     promises.push(this.competencyProvider.getCompetencySummary(competency.competency.id, undefined, undefined, |                     promises.push(this.competencyProvider.getCompetencySummary(competency.competency.id, undefined, undefined, | ||||||
|                             true)); |                             true)); | ||||||
|  | 
 | ||||||
|  |                     if (competency.coursemodules) { | ||||||
|  |                         competency.coursemodules.forEach((module) => { | ||||||
|  |                             promises.push(this.filterHelper.getFilters('module', module.id, {courseId: course.id})); | ||||||
|  |                         }); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if (competency.plans) { | ||||||
|  |                         competency.plans.forEach((plan) => { | ||||||
|  |                             promises.push(this.filterHelper.getFilters('user', plan.userid)); | ||||||
|  |                         }); | ||||||
|  |                     } | ||||||
|                 }); |                 }); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,8 +17,8 @@ | |||||||
|         <ion-card *ngIf="completion && tracked"> |         <ion-card *ngIf="completion && tracked"> | ||||||
|             <ion-item-divider>{{ 'addon.coursecompletion.requiredcriteria' | translate }}</ion-item-divider> |             <ion-item-divider>{{ 'addon.coursecompletion.requiredcriteria' | translate }}</ion-item-divider> | ||||||
|             <ion-item class="hidden-tablet" text-wrap *ngFor="let criteria of completion.completions"> |             <ion-item class="hidden-tablet" text-wrap *ngFor="let criteria of completion.completions"> | ||||||
|                 <h2><core-format-text clean="true" [text]="criteria.details.criteria"></core-format-text></h2> |                 <h2><core-format-text clean="true" [text]="criteria.details.criteria" [filter]="false"></core-format-text></h2> | ||||||
|                 <p><core-format-text clean="true" [text]="criteria.details.requirement"></core-format-text></p> |                 <p><core-format-text clean="true" [text]="criteria.details.requirement" [filter]="false"></core-format-text></p> | ||||||
|                 <strong item-end>{{ criteria.status }}</strong> |                 <strong item-end>{{ criteria.status }}</strong> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item class="hidden-phone" text-wrap> |             <ion-item class="hidden-phone" text-wrap> | ||||||
| @ -31,10 +31,10 @@ | |||||||
|                     <ion-col><strong>{{ 'addon.coursecompletion.completiondate' | translate }}</strong></ion-col> |                     <ion-col><strong>{{ 'addon.coursecompletion.completiondate' | translate }}</strong></ion-col> | ||||||
|                 </ion-row> |                 </ion-row> | ||||||
|                 <ion-row *ngFor="let criteria of completion.completions"> |                 <ion-row *ngFor="let criteria of completion.completions"> | ||||||
|                     <ion-col><core-format-text clean="true" [text]="criteria.title"></core-format-text></ion-col> |                     <ion-col><core-format-text clean="true" [text]="criteria.title" [filter]="false"></core-format-text></ion-col> | ||||||
|                     <ion-col><core-format-text clean="true" [text]="criteria.details.criteria"></core-format-text></ion-col> |                     <ion-col><core-format-text clean="true" [text]="criteria.details.criteria" [filter]="false"></core-format-text></ion-col> | ||||||
|                     <ion-col><core-format-text clean="true" [text]="criteria.details.requirement"></core-format-text></ion-col> |                     <ion-col><core-format-text clean="true" [text]="criteria.details.requirement" [filter]="false"></core-format-text></ion-col> | ||||||
|                     <ion-col><core-format-text [text]="criteria.details.status"></core-format-text></ion-col> |                     <ion-col><core-format-text [text]="criteria.details.status" [filter]="false"></core-format-text></ion-col> | ||||||
|                     <ion-col>{{ criteria.status }}</ion-col> |                     <ion-col>{{ criteria.status }}</ion-col> | ||||||
|                     <ion-col *ngIf="criteria.timecompleted">{{ criteria.timecompleted * 1000 | coreFormatDate :'strftimedatetimeshort' }}</ion-col> |                     <ion-col *ngIf="criteria.timecompleted">{{ criteria.timecompleted * 1000 | coreFormatDate :'strftimedatetimeshort' }}</ion-col> | ||||||
|                     <ion-col *ngIf="!criteria.timecompleted"></ion-col> |                     <ion-col *ngIf="!criteria.timecompleted"></ion-col> | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title>{{ title }}</ion-title> | ||||||
|     </ion-navbar> |     </ion-navbar> | ||||||
| </ion-header> | </ion-header> | ||||||
| <ion-content> | <ion-content> | ||||||
|  | |||||||
							
								
								
									
										34
									
								
								src/addon/filter/activitynames/activitynames.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/activitynames/activitynames.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterActivityNamesHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterActivityNamesHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterActivityNamesModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterActivityNamesHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/activitynames/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/activitynames/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Activity names filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterActivityNamesHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterActivityNamesHandler'; | ||||||
|  |     filterName = 'activitynames'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/algebra/algebra.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/algebra/algebra.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterAlgebraHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterAlgebraHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterAlgebraModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterAlgebraHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/algebra/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/algebra/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Algebra notation filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterAlgebraHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterAlgebraHandler'; | ||||||
|  |     filterName = 'algebra'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/censor/censor.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/censor/censor.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterCensorHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterCensorHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterCensorModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterCensorHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/censor/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/censor/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Word censorship filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterCensorHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterCensorHandler'; | ||||||
|  |     filterName = 'censor'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/data/data.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/data/data.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterDataHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterDataHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterDataModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterDataHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/data/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/data/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Database auto-link filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterDataHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterDataHandler'; | ||||||
|  |     filterName = 'data'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/emailprotect/emailprotect.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/emailprotect/emailprotect.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterEmailProtectHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterEmailProtectHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterEmailProtectModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterEmailProtectHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/emailprotect/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/emailprotect/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Email protection filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterEmailProtectHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterEmailProtectHandler'; | ||||||
|  |     filterName = 'emailprotect'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/emoticon/emoticon.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/emoticon/emoticon.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterEmoticonHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterEmoticonHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterEmoticonModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterEmoticonHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/emoticon/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/emoticon/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Emoticon filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterEmoticonHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterEmoticonHandler'; | ||||||
|  |     filterName = 'emoticon'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										49
									
								
								src/addon/filter/filter.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/addon/filter/filter.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { AddonFilterActivityNamesModule } from './activitynames/activitynames.module'; | ||||||
|  | import { AddonFilterAlgebraModule } from './algebra/algebra.module'; | ||||||
|  | import { AddonFilterCensorModule } from './censor/censor.module'; | ||||||
|  | import { AddonFilterDataModule } from './data/data.module'; | ||||||
|  | import { AddonFilterEmailProtectModule } from './emailprotect/emailprotect.module'; | ||||||
|  | import { AddonFilterEmoticonModule } from './emoticon/emoticon.module'; | ||||||
|  | import { AddonFilterGlossaryModule } from './glossary/glossary.module'; | ||||||
|  | import { AddonFilterMediaPluginModule } from './mediaplugin/mediaplugin.module'; | ||||||
|  | import { AddonFilterMultilangModule } from './multilang/multilang.module'; | ||||||
|  | import { AddonFilterTexModule } from './tex/tex.module'; | ||||||
|  | import { AddonFilterTidyModule } from './tidy/tidy.module'; | ||||||
|  | import { AddonFilterUrlToLinkModule } from './urltolink/urltolink.module'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [], | ||||||
|  |     imports: [ | ||||||
|  |         AddonFilterActivityNamesModule, | ||||||
|  |         AddonFilterAlgebraModule, | ||||||
|  |         AddonFilterCensorModule, | ||||||
|  |         AddonFilterDataModule, | ||||||
|  |         AddonFilterEmailProtectModule, | ||||||
|  |         AddonFilterEmoticonModule, | ||||||
|  |         AddonFilterGlossaryModule, | ||||||
|  |         AddonFilterMediaPluginModule, | ||||||
|  |         AddonFilterMultilangModule, | ||||||
|  |         AddonFilterTexModule, | ||||||
|  |         AddonFilterTidyModule, | ||||||
|  |         AddonFilterUrlToLinkModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |     ], | ||||||
|  |     exports: [] | ||||||
|  | }) | ||||||
|  | export class AddonFilterModule { } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/glossary/glossary.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/glossary/glossary.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterGlossaryHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterGlossaryHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterGlossaryModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterGlossaryHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/glossary/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/glossary/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Glossary auto-link filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterGlossaryHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterGlossaryHandler'; | ||||||
|  |     filterName = 'glossary'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/mediaplugin/mediaplugin.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/mediaplugin/mediaplugin.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterMediaPluginHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterMediaPluginHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterMediaPluginModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterMediaPluginHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										139
									
								
								src/addon/filter/mediaplugin/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/addon/filter/mediaplugin/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,139 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFilter, CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreTextUtilsProvider } from '@providers/utils/text'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Multimedia filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterMediaPluginHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterMediaPluginHandler'; | ||||||
|  |     filterName = 'mediaplugin'; | ||||||
|  | 
 | ||||||
|  |     constructor(private textUtils: CoreTextUtilsProvider) { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Filter some text. | ||||||
|  |      * | ||||||
|  |      * @param text The text to filter. | ||||||
|  |      * @param filter The filter. | ||||||
|  |      * @param options Options passed to the filters. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Filtered text (or promise resolved with the filtered text). | ||||||
|  |      */ | ||||||
|  |     filter(text: string, filter: CoreFilterFilter, options: CoreFilterFormatTextOptions, siteId?: string) | ||||||
|  |             : string | Promise<string> { | ||||||
|  | 
 | ||||||
|  |         const div = document.createElement('div'); | ||||||
|  |         div.innerHTML = text; | ||||||
|  | 
 | ||||||
|  |         const videos = Array.from(div.querySelectorAll('video')); | ||||||
|  | 
 | ||||||
|  |         videos.forEach((video) => { | ||||||
|  |             this.treatVideoFilters(video); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         return div.innerHTML; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Treat video filters. Currently only treating youtube video using video JS. | ||||||
|  |      * | ||||||
|  |      * @param el Video element. | ||||||
|  |      * @param navCtrl NavController to use. | ||||||
|  |      */ | ||||||
|  |     protected treatVideoFilters(video: HTMLElement): void { | ||||||
|  |         // Treat Video JS Youtube video links and translate them to iframes.
 | ||||||
|  |         if (!video.classList.contains('video-js')) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const data = this.textUtils.parseJSON(video.getAttribute('data-setup') || video.getAttribute('data-setup-lazy') || '{}'), | ||||||
|  |             youtubeData = data.techOrder && data.techOrder[0] && data.techOrder[0] == 'youtube' && | ||||||
|  |                     this.parseYoutubeUrl(data.sources && data.sources[0] && data.sources[0].src); | ||||||
|  | 
 | ||||||
|  |         if (!youtubeData || !youtubeData.videoId) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const iframe = document.createElement('iframe'); | ||||||
|  |         iframe.id = video.id; | ||||||
|  |         iframe.src = 'https://www.youtube.com/embed/' + youtubeData.videoId; // Don't apply other params to align with Moodle web.
 | ||||||
|  |         iframe.setAttribute('frameborder', '0'); | ||||||
|  |         iframe.setAttribute('allowfullscreen', '1'); | ||||||
|  |         iframe.width = '100%'; | ||||||
|  |         iframe.height = '300'; | ||||||
|  | 
 | ||||||
|  |         // Replace video tag by the iframe.
 | ||||||
|  |         video.parentNode.replaceChild(iframe, video); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Parse a YouTube URL. | ||||||
|  |      * Based on Youtube.parseUrl from Moodle media/player/videojs/amd/src/Youtube-lazy.js | ||||||
|  |      * | ||||||
|  |      * @param url URL of the video. | ||||||
|  |      * @return Data of the video. | ||||||
|  |      */ | ||||||
|  |     protected parseYoutubeUrl(url: string): {videoId: string, listId?: string, start?: number} { | ||||||
|  |         const result = { | ||||||
|  |             videoId: null, | ||||||
|  |             listId: null, | ||||||
|  |             start: null | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         if (!url) { | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         url = this.textUtils.decodeHTML(url); | ||||||
|  | 
 | ||||||
|  |         // Get the video ID.
 | ||||||
|  |         let match = url.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/); | ||||||
|  | 
 | ||||||
|  |         if (match && match[2].length === 11) { | ||||||
|  |             result.videoId = match[2]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Now get the playlist (if any).
 | ||||||
|  |         match = url.match(/[?&]list=([^#\&\?]+)/); | ||||||
|  | 
 | ||||||
|  |         if (match && match[1]) { | ||||||
|  |             result.listId = match[1]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Now get the start time (if any).
 | ||||||
|  |         match = url.match(/[?&]start=(\d+)/); | ||||||
|  | 
 | ||||||
|  |         if (match && match[1]) { | ||||||
|  |             result.start = parseInt(match[1], 10); | ||||||
|  |         } else { | ||||||
|  |             // No start param, but it could have a time param.
 | ||||||
|  |             match = url.match(/[?&]t=(\d+h)?(\d+m)?(\d+s)?/); | ||||||
|  |             if (match) { | ||||||
|  |                 result.start = (match[1] ? parseInt(match[1], 10) * 3600 : 0) + (match[2] ? parseInt(match[2], 10) * 60 : 0) + | ||||||
|  |                         (match[3] ? parseInt(match[3], 10) : 0); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/multilang/multilang.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/multilang/multilang.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterMultilangHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterMultilangHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterMultilangModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterMultilangHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										93
									
								
								src/addon/filter/multilang/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/addon/filter/multilang/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreSitesProvider } from '@providers/sites'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFilter, CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreLangProvider } from '@providers/lang'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the Multilang filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterMultilangHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterMultilangHandler'; | ||||||
|  |     filterName = 'multilang'; | ||||||
|  | 
 | ||||||
|  |     constructor(private langProvider: CoreLangProvider, | ||||||
|  |             private sitesProvider: CoreSitesProvider) { | ||||||
|  |         super(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Filter some text. | ||||||
|  |      * | ||||||
|  |      * @param text The text to filter. | ||||||
|  |      * @param filter The filter. | ||||||
|  |      * @param options Options passed to the filters. | ||||||
|  |      * @param siteId Site ID. If not defined, current site. | ||||||
|  |      * @return Filtered text (or promise resolved with the filtered text). | ||||||
|  |      */ | ||||||
|  |     filter(text: string, filter: CoreFilterFilter, options: CoreFilterFormatTextOptions, siteId?: string) | ||||||
|  |             : string | Promise<string> { | ||||||
|  | 
 | ||||||
|  |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|  | 
 | ||||||
|  |             // Don't apply this filter if Moodle is 3.7 or higher and the WS already filtered the content.
 | ||||||
|  |             if (!this.shouldBeApplied(options, site)) { | ||||||
|  |                 return text; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return this.langProvider.getCurrentLanguage().then((language) => { | ||||||
|  |                 // Match the current language.
 | ||||||
|  |                 const anyLangRegEx = /<(?:lang|span)[^>]+lang="[a-zA-Z0-9_-]+"[^>]*>(.*?)<\/(?:lang|span)>/g; | ||||||
|  |                 let currentLangRegEx = new RegExp('<(?:lang|span)[^>]+lang="' + language + '"[^>]*>(.*?)<\/(?:lang|span)>', 'g'); | ||||||
|  | 
 | ||||||
|  |                 if (!text.match(currentLangRegEx)) { | ||||||
|  |                     // Current lang not found. Try to find the first language.
 | ||||||
|  |                     const matches = text.match(anyLangRegEx); | ||||||
|  |                     if (matches && matches[0]) { | ||||||
|  |                         language = matches[0].match(/lang="([a-zA-Z0-9_-]+)"/)[1]; | ||||||
|  |                         currentLangRegEx = new RegExp('<(?:lang|span)[^>]+lang="' + language + '"[^>]*>(.*?)<\/(?:lang|span)>', | ||||||
|  |                                 'g'); | ||||||
|  |                     } else { | ||||||
|  |                         // No multi-lang tag found, stop.
 | ||||||
|  |                         return text; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 // Extract contents of current language.
 | ||||||
|  |                 text = text.replace(currentLangRegEx, '$1'); | ||||||
|  |                 // Delete the rest of languages
 | ||||||
|  |                 text = text.replace(anyLangRegEx, ''); | ||||||
|  | 
 | ||||||
|  |                 return text; | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         // The filter should be applied if site is older than 3.7 or the WS didn't filter the text.
 | ||||||
|  |         return options.wsNotFiltered || !site.isVersionGreaterEqualThan('3.7'); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/tex/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/tex/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the TeX notation filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterTexHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterTexHandler'; | ||||||
|  |     filterName = 'tex'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/tex/tex.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/tex/tex.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterTexHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterTexHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterTexModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterTexHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/tidy/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/tidy/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the HTML tidy filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterTidyHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterTidyHandler'; | ||||||
|  |     filterName = 'tidy'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/tidy/tidy.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/tidy/tidy.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterTidyHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterTidyHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterTidyModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterTidyHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								src/addon/filter/urltolink/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/addon/filter/urltolink/providers/handler.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | 
 | ||||||
|  | // (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 { Injectable } from '@angular/core'; | ||||||
|  | import { CoreFilterDefaultHandler } from '@core/filter/providers/default-filter'; | ||||||
|  | import { CoreFilterFormatTextOptions } from '@core/filter/providers/filter'; | ||||||
|  | import { CoreSite } from '@classes/site'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handler to support the URL to link and images filter. | ||||||
|  |  */ | ||||||
|  | @Injectable() | ||||||
|  | export class AddonFilterUrlToLinkHandler extends CoreFilterDefaultHandler { | ||||||
|  |     name = 'AddonFilterUrlToLinkHandler'; | ||||||
|  |     filterName = 'urltolink'; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  | 
 | ||||||
|  |         // This filter is handled by Moodle, nothing to do in the app.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if the filter should be applied in a certain site based on some filter options. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @param site Site. | ||||||
|  |      * @return Whether filter should be applied. | ||||||
|  |      */ | ||||||
|  |     shouldBeApplied(options: CoreFilterFormatTextOptions, site?: CoreSite): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								src/addon/filter/urltolink/urltolink.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/addon/filter/urltolink/urltolink.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // (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 { NgModule } from '@angular/core'; | ||||||
|  | import { IonicModule } from 'ionic-angular'; | ||||||
|  | import { CoreFilterDelegate } from '@core/filter/providers/delegate'; | ||||||
|  | import { AddonFilterUrlToLinkHandler } from './providers/handler'; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     declarations: [ | ||||||
|  |     ], | ||||||
|  |     imports: [ | ||||||
|  |         IonicModule | ||||||
|  |     ], | ||||||
|  |     providers: [ | ||||||
|  |         AddonFilterUrlToLinkHandler | ||||||
|  |     ] | ||||||
|  | }) | ||||||
|  | export class AddonFilterUrlToLinkModule { | ||||||
|  |     constructor(filterDelegate: CoreFilterDelegate, handler: AddonFilterUrlToLinkHandler) { | ||||||
|  |         filterDelegate.registerHandler(handler); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -7,7 +7,7 @@ | |||||||
|             <a ion-item text-wrap *ngFor="let contact of contacts" [title]="contact.fullname" (click)="selectUser(contact.id)" [class.core-split-item-selected]="contact.id == selectedUserId" class="addon-messages-conversation-item"> |             <a ion-item text-wrap *ngFor="let contact of contacts" [title]="contact.fullname" (click)="selectUser(contact.id)" [class.core-split-item-selected]="contact.id == selectedUserId" class="addon-messages-conversation-item"> | ||||||
|                 <ion-avatar item-start core-user-avatar [user]="contact" [checkOnline]="contact.showonlinestatus" [linkProfile]="false"></ion-avatar> |                 <ion-avatar item-start core-user-avatar [user]="contact" [checkOnline]="contact.showonlinestatus" [linkProfile]="false"></ion-avatar> | ||||||
|                 <h2> |                 <h2> | ||||||
|                     <core-format-text [text]="contact.fullname"></core-format-text> |                     {{ contact.fullname }} | ||||||
|                     <core-icon *ngIf="contact.isblocked" name="fa-ban" item-end></core-icon> |                     <core-icon *ngIf="contact.isblocked" name="fa-ban" item-end></core-icon> | ||||||
|                 </h2> |                 </h2> | ||||||
|             </a> |             </a> | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ | |||||||
|         <ion-list no-margin> |         <ion-list no-margin> | ||||||
|             <a ion-item text-wrap *ngFor="let request of requests" [title]="request.fullname" (click)="selectUser(request.id)" [class.core-split-item-selected]="request.id == selectedUserId" class="addon-messages-conversation-item"> |             <a ion-item text-wrap *ngFor="let request of requests" [title]="request.fullname" (click)="selectUser(request.id)" [class.core-split-item-selected]="request.id == selectedUserId" class="addon-messages-conversation-item"> | ||||||
|                 <ion-avatar item-start core-user-avatar [user]="request" [linkProfile]="false"></ion-avatar> |                 <ion-avatar item-start core-user-avatar [user]="request" [linkProfile]="false"></ion-avatar> | ||||||
|                 <h2><core-format-text [text]="request.fullname"></core-format-text></h2> |                 <h2>{{ request.fullname }}</h2> | ||||||
|                 <p *ngIf="!request.iscontact && !request.confirmedOrDeclined">{{ 'addon.messages.wouldliketocontactyou' | translate }}</p> |                 <p *ngIf="!request.iscontact && !request.confirmedOrDeclined">{{ 'addon.messages.wouldliketocontactyou' | translate }}</p> | ||||||
|             </a> |             </a> | ||||||
|         </ion-list> |         </ion-list> | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ | |||||||
|                     <!-- Don't show deleted users --> |                     <!-- Don't show deleted users --> | ||||||
|                     <a ion-item text-wrap *ngIf="contact.profileimageurl || contact.profileimageurlsmall"  [title]="contact.fullname" (click)="gotoDiscussion(contact.id)" [class.core-split-item-selected]="contact.id == discussionUserId" class="addon-messages-conversation-item"> |                     <a ion-item text-wrap *ngIf="contact.profileimageurl || contact.profileimageurlsmall"  [title]="contact.fullname" (click)="gotoDiscussion(contact.id)" [class.core-split-item-selected]="contact.id == discussionUserId" class="addon-messages-conversation-item"> | ||||||
|                         <ion-avatar core-user-avatar [user]="contact" item-start [checkOnline]="contact.showonlinestatus"></ion-avatar> |                         <ion-avatar core-user-avatar [user]="contact" item-start [checkOnline]="contact.showonlinestatus"></ion-avatar> | ||||||
|                         <h2><core-format-text [text]="contact.fullname"></core-format-text></h2> |                         <h2>{{ contact.fullname }}</h2> | ||||||
|                     </a> |                     </a> | ||||||
|                 </ng-container> |                 </ng-container> | ||||||
|             </ng-container> |             </ng-container> | ||||||
|  | |||||||
| @ -14,22 +14,20 @@ | |||||||
|             </ion-item-divider> |             </ion-item-divider> | ||||||
|             <a ion-item text-wrap *ngFor="let result of search.results" [title]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)" [class.core-split-item-selected]="result.userid == discussionUserId" class="addon-message-discussion"> |             <a ion-item text-wrap *ngFor="let result of search.results" [title]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)" [class.core-split-item-selected]="result.userid == discussionUserId" class="addon-message-discussion"> | ||||||
|                 <ion-avatar core-user-avatar [user]="result" item-start [checkOnline]="result.showonlinestatus"></ion-avatar> |                 <ion-avatar core-user-avatar [user]="result" item-start [checkOnline]="result.showonlinestatus"></ion-avatar> | ||||||
|                 <h2><core-format-text [text]="result.fullname"></core-format-text></h2> |                 <h2>{{ result.fullname }}</h2> | ||||||
|                 <p><core-format-text clean="true" singleLine="true" [text]="result.lastmessage"></core-format-text></p> |                 <p><core-format-text clean="true" singleLine="true" [text]="result.lastmessage" contextLevel="system" [contextInstanceId]="0"></core-format-text></p> | ||||||
|             </a> |             </a> | ||||||
|         </ion-list> |         </ion-list> | ||||||
| 
 | 
 | ||||||
|         <ion-list *ngIf="!search.showResults" no-margin> |         <ion-list *ngIf="!search.showResults" no-margin> | ||||||
|             <a ion-item text-wrap *ngFor="let discussion of discussions" [title]="discussion.fullname" (click)="gotoDiscussion(discussion.message.user)" [class.core-split-item-selected]="discussion.message.user == discussionUserId" class="addon-message-discussion"> |             <a ion-item text-wrap *ngFor="let discussion of discussions" [title]="discussion.fullname" (click)="gotoDiscussion(discussion.message.user)" [class.core-split-item-selected]="discussion.message.user == discussionUserId" class="addon-message-discussion"> | ||||||
|                 <ion-avatar core-user-avatar [user]="discussion" item-start [checkOnline]="discussion.showonlinestatus"></ion-avatar> |                 <ion-avatar core-user-avatar [user]="discussion" item-start [checkOnline]="discussion.showonlinestatus"></ion-avatar> | ||||||
|                 <h2> |                 <h2>{{ discussion.fullname }}</h2> | ||||||
|                     <core-format-text [text]="discussion.fullname"></core-format-text> |  | ||||||
|                 </h2> |  | ||||||
|                 <ion-note *ngIf="discussion.message.timecreated > 0 || discussion.unread"> |                 <ion-note *ngIf="discussion.message.timecreated > 0 || discussion.unread"> | ||||||
|                     <span *ngIf="discussion.unread" class="core-primary-circle"></span> |                     <span *ngIf="discussion.unread" class="core-primary-circle"></span> | ||||||
|                     <span *ngIf="discussion.message.timecreated > 0">{{discussion.message.timecreated / 1000 | coreDateDayOrTime}}</span> |                     <span *ngIf="discussion.message.timecreated > 0">{{discussion.message.timecreated / 1000 | coreDateDayOrTime}}</span> | ||||||
|                 </ion-note> |                 </ion-note> | ||||||
|                 <p><core-format-text clean="true" singleLine="true" [text]="discussion.message.message"></core-format-text></p> |                 <p><core-format-text clean="true" singleLine="true" [text]="discussion.message.message" contextLevel="system" [contextInstanceId]="0"></core-format-text></p> | ||||||
|             </a> |             </a> | ||||||
|         </ion-list> |         </ion-list> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,15 +18,15 @@ | |||||||
|             <div class="item-avatar-center"> |             <div class="item-avatar-center"> | ||||||
|                 <img class="avatar" [src]="conversation.imageurl" core-external-content [alt]="conversation.name" role="presentation" onError="this.src='assets/img/group-avatar.png'"> |                 <img class="avatar" [src]="conversation.imageurl" core-external-content [alt]="conversation.name" role="presentation" onError="this.src='assets/img/group-avatar.png'"> | ||||||
|             </div> |             </div> | ||||||
|             <h2><core-format-text [text]="conversation.name"></core-format-text></h2> |             <h2><core-format-text [text]="conversation.name" contextLevel="system" [contextInstanceId]="0"></core-format-text></h2> | ||||||
|             <p><core-format-text *ngIf="conversation.subname" [text]="conversation.subname"></core-format-text></p> |             <p><core-format-text *ngIf="conversation.subname" [text]="conversation.subname" contextLevel="system" [contextInstanceId]="0"></core-format-text></p> | ||||||
|             <p>{{ 'addon.messages.numparticipants' | translate:{$a: conversation.membercount} }}</p> |             <p>{{ 'addon.messages.numparticipants' | translate:{$a: conversation.membercount} }}</p> | ||||||
|         </ion-item> |         </ion-item> | ||||||
| 
 | 
 | ||||||
|         <a ion-item text-wrap *ngFor="let member of members" (click)="closeModal(member.id)" class="addon-messages-conversation-item"> |         <a ion-item text-wrap *ngFor="let member of members" (click)="closeModal(member.id)" class="addon-messages-conversation-item"> | ||||||
|             <ion-avatar core-user-avatar [user]="member" [linkProfile]="false" [checkOnline]="member.showonlinestatus" item-start></ion-avatar> |             <ion-avatar core-user-avatar [user]="member" [linkProfile]="false" [checkOnline]="member.showonlinestatus" item-start></ion-avatar> | ||||||
|             <h2> |             <h2> | ||||||
|                 <core-format-text [text]="member.fullname"></core-format-text> |                 {{ member.fullname }} | ||||||
|                 <core-icon name="fa-ban" *ngIf="member.isblocked" [label]="'addon.messages.contactblocked' | translate"></core-icon> |                 <core-icon name="fa-ban" *ngIf="member.isblocked" [label]="'addon.messages.contactblocked' | translate"></core-icon> | ||||||
|             </h2> |             </h2> | ||||||
|         </a> |         </a> | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ import { | |||||||
|     AddonMessagesProvider, AddonMessagesConversationFormatted, AddonMessagesConversationMember |     AddonMessagesProvider, AddonMessagesConversationFormatted, AddonMessagesConversationMember | ||||||
| } from '../../providers/messages'; | } from '../../providers/messages'; | ||||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||||
|  | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Page that displays the list of conversations, including group conversations. |  * Page that displays the list of conversations, including group conversations. | ||||||
| @ -38,7 +39,7 @@ export class AddonMessagesConversationInfoPage implements OnInit { | |||||||
|     protected conversationId: number; |     protected conversationId: number; | ||||||
| 
 | 
 | ||||||
|     constructor(private messagesProvider: AddonMessagesProvider, private domUtils: CoreDomUtilsProvider, navParams: NavParams, |     constructor(private messagesProvider: AddonMessagesProvider, private domUtils: CoreDomUtilsProvider, navParams: NavParams, | ||||||
|             protected viewCtrl: ViewController) { |             protected viewCtrl: ViewController, sitesProvider: CoreSitesProvider) { | ||||||
|         this.conversationId = navParams.get('conversationId'); |         this.conversationId = navParams.get('conversationId'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
|         <ion-title> |         <ion-title> | ||||||
|             <img *ngIf="loaded && !otherMember && conversationImage" class="core-bar-button-image" [src]="conversationImage" [alt]="title" onError="this.src='assets/img/group-avatar.png'" core-external-content role="presentation" [siteId]="siteId || null"> |             <img *ngIf="loaded && !otherMember && conversationImage" class="core-bar-button-image" [src]="conversationImage" [alt]="title" onError="this.src='assets/img/group-avatar.png'" core-external-content role="presentation" [siteId]="siteId || null"> | ||||||
|             <ion-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" core-user-avatar [user]="otherMember" [linkProfile]="false" [checkOnline]="otherMember.showonlinestatus" item-start (click)="showInfo && viewInfo()"></ion-avatar> |             <ion-avatar *ngIf="loaded && otherMember" class="core-bar-button-image" core-user-avatar [user]="otherMember" [linkProfile]="false" [checkOnline]="otherMember.showonlinestatus" item-start (click)="showInfo && viewInfo()"></ion-avatar> | ||||||
|             <core-format-text [text]="title" (click)="showInfo && !isGroup && viewInfo()"></core-format-text> |             <core-format-text [text]="title" contextLevel="system" [contextInstanceId]="0" (click)="showInfo && !isGroup && viewInfo()"></core-format-text> | ||||||
|             <core-icon *ngIf="conversation && conversation.isfavourite" name="fa-star" [label]="'core.favourites' | translate"></core-icon> |             <core-icon *ngIf="conversation && conversation.isfavourite" name="fa-star" [label]="'core.favourites' | translate"></core-icon> | ||||||
|             <core-icon *ngIf="conversation && conversation.ismuted" name="volume-off" [label]="'addon.messages.mutedconversation' | translate"></core-icon> |             <core-icon *ngIf="conversation && conversation.ismuted" name="volume-off" [label]="'addon.messages.mutedconversation' | translate"></core-icon> | ||||||
|         </ion-title> |         </ion-title> | ||||||
| @ -58,7 +58,7 @@ | |||||||
| 
 | 
 | ||||||
|                     <!-- Some messages have <p> and some others don't. Add a <p> so they all have same styles. --> |                     <!-- Some messages have <p> and some others don't. Add a <p> so they all have same styles. --> | ||||||
|                     <p class="addon-message-text"> |                     <p class="addon-message-text"> | ||||||
|                         <core-format-text (afterRender)="last && scrollToBottom()" [text]="message.text"></core-format-text> |                         <core-format-text (afterRender)="last && scrollToBottom()" [text]="message.text" contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||||
|                     </p> |                     </p> | ||||||
| 
 | 
 | ||||||
|                     <button ion-button icon-only clear="true" *ngIf="!message.sending && showDelete" (click)="deleteMessage(message, index)" class="addon-messages-delete-button" [@coreSlideInOut]="'fromRight'" [attr.aria-label]=" 'addon.messages.deletemessage' | translate"> |                     <button ion-button icon-only clear="true" *ngIf="!message.sending && showDelete" (click)="deleteMessage(message, index)" class="addon-messages-delete-button" [@coreSlideInOut]="'fromRight'" [attr.aria-label]=" 'addon.messages.deletemessage' | translate"> | ||||||
|  | |||||||
| @ -99,7 +99,7 @@ | |||||||
|         <ion-avatar *ngIf="conversation.type != typeGroup" core-user-avatar [user]="conversation.otherUser" [linkProfile]="false" [checkOnline]="conversation.showonlinestatus" item-start></ion-avatar> |         <ion-avatar *ngIf="conversation.type != typeGroup" core-user-avatar [user]="conversation.otherUser" [linkProfile]="false" [checkOnline]="conversation.showonlinestatus" item-start></ion-avatar> | ||||||
| 
 | 
 | ||||||
|         <h2> |         <h2> | ||||||
|             <core-format-text [text]="conversation.name"></core-format-text> |             <core-format-text [text]="conversation.name" contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||||
|             <core-icon name="fa-ban" *ngIf="conversation.isblocked" [label]="'addon.messages.contactblocked' | translate"></core-icon> |             <core-icon name="fa-ban" *ngIf="conversation.isblocked" [label]="'addon.messages.contactblocked' | translate"></core-icon> | ||||||
|             <core-icon *ngIf="conversation.ismuted" name="volume-off" [label]="'addon.messages.mutedconversation' | translate"></core-icon> |             <core-icon *ngIf="conversation.ismuted" name="volume-off" [label]="'addon.messages.mutedconversation' | translate"></core-icon> | ||||||
|         </h2> |         </h2> | ||||||
| @ -107,11 +107,11 @@ | |||||||
|             <ion-badge *ngIf="conversation.unreadcount > 0">{{ conversation.unreadcount }}</ion-badge> |             <ion-badge *ngIf="conversation.unreadcount > 0">{{ conversation.unreadcount }}</ion-badge> | ||||||
|             <span *ngIf="conversation.lastmessagedate > 0">{{conversation.lastmessagedate | coreDateDayOrTime}}</span> |             <span *ngIf="conversation.lastmessagedate > 0">{{conversation.lastmessagedate | coreDateDayOrTime}}</span> | ||||||
|         </ion-note> |         </ion-note> | ||||||
|         <p *ngIf="conversation.subname"><core-format-text [text]="conversation.subname"></core-format-text></p> |         <p *ngIf="conversation.subname"><core-format-text [text]="conversation.subname" contextLevel="system" [contextInstanceId]="0"></core-format-text></p> | ||||||
|         <p class="addon-message-last-message"> |         <p class="addon-message-last-message"> | ||||||
|             <span *ngIf="conversation.sentfromcurrentuser" class="addon-message-last-message-user">{{ 'addon.messages.you' | translate }}</span> |             <span *ngIf="conversation.sentfromcurrentuser" class="addon-message-last-message-user">{{ 'addon.messages.you' | translate }}</span> | ||||||
|             <core-format-text *ngIf="!conversation.sentfromcurrentuser && conversation.type == typeGroup && conversation.members[0]" [text]="conversation.members[0].fullname + ':'" class="addon-message-last-message-user"></core-format-text> |             <span *ngIf="!conversation.sentfromcurrentuser && conversation.type == typeGroup && conversation.members[0]" class="addon-message-last-message-user">{{ conversation.members[0].fullname + ':' }}</span> | ||||||
|             <core-format-text clean="true" singleLine="true" [text]="conversation.lastmessage" class="addon-message-last-message-text"></core-format-text> |             <core-format-text clean="true" singleLine="true" [text]="conversation.lastmessage" class="addon-message-last-message-text" contextLevel="system" [contextInstanceId]="0"></core-format-text> | ||||||
|         </p> |         </p> | ||||||
|     </a> |     </a> | ||||||
| </ng-template> | </ng-template> | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ | |||||||
|         <a ion-item text-wrap *ngFor="let result of item.results" [title]="result.fullname" (click)="openConversation(result)" [class.core-split-item-selected]="result == selectedResult" class="addon-message-discussion"> |         <a ion-item text-wrap *ngFor="let result of item.results" [title]="result.fullname" (click)="openConversation(result)" [class.core-split-item-selected]="result == selectedResult" class="addon-message-discussion"> | ||||||
|             <ion-avatar item-start core-user-avatar [user]="result" [checkOnline]="true" [linkProfile]="false"></ion-avatar> |             <ion-avatar item-start core-user-avatar [user]="result" [checkOnline]="true" [linkProfile]="false"></ion-avatar> | ||||||
|             <h2> |             <h2> | ||||||
|                 <core-format-text [text]="result.fullname" [highlight]="result.highlightName"></core-format-text> |                 <core-format-text [text]="result.fullname" [highlight]="result.highlightName" [filter]="false"></core-format-text> | ||||||
|                 <core-icon name="fa-ban" *ngIf="result.isblocked" [label]="'addon.messages.contactblocked' | translate"></core-icon> |                 <core-icon name="fa-ban" *ngIf="result.isblocked" [label]="'addon.messages.contactblocked' | translate"></core-icon> | ||||||
|             </h2> |             </h2> | ||||||
|             <ion-note *ngIf="result.lastmessagedate > 0"> |             <ion-note *ngIf="result.lastmessagedate > 0"> | ||||||
| @ -41,7 +41,7 @@ | |||||||
|             </ion-note> |             </ion-note> | ||||||
|             <p class="addon-message-last-message"> |             <p class="addon-message-last-message"> | ||||||
|                 <span *ngIf="result.sentfromcurrentuser" class="addon-message-last-message-user">{{ 'addon.messages.you' | translate }}</span> |                 <span *ngIf="result.sentfromcurrentuser" class="addon-message-last-message-user">{{ 'addon.messages.you' | translate }}</span> | ||||||
|                 <core-format-text clean="true" singleLine="true" [text]="result.lastmessage" [highlight]="result.highlightMessage" class="addon-message-last-message-text"></core-format-text> |                 <core-format-text clean="true" singleLine="true" [text]="result.lastmessage" [highlight]="result.highlightMessage" contextLevel="system" [contextInstanceId]="0" class="addon-message-last-message-text"></core-format-text> | ||||||
|             </p> |             </p> | ||||||
|         </a> |         </a> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -19,12 +19,12 @@ import { CoreCronHandler } from '@providers/cron'; | |||||||
| import { CoreSitesProvider } from '@providers/sites'; | import { CoreSitesProvider } from '@providers/sites'; | ||||||
| import { CoreEventsProvider } from '@providers/events'; | import { CoreEventsProvider } from '@providers/events'; | ||||||
| import { CoreAppProvider } from '@providers/app'; | import { CoreAppProvider } from '@providers/app'; | ||||||
| import { CoreTextUtilsProvider } from '@providers/utils/text'; |  | ||||||
| import { CoreUtilsProvider } from '@providers/utils/utils'; | import { CoreUtilsProvider } from '@providers/utils/utils'; | ||||||
| import { CoreLocalNotificationsProvider } from '@providers/local-notifications'; | import { CoreLocalNotificationsProvider } from '@providers/local-notifications'; | ||||||
| import { CorePushNotificationsProvider } from '@core/pushnotifications/providers/pushnotifications'; | import { CorePushNotificationsProvider } from '@core/pushnotifications/providers/pushnotifications'; | ||||||
| import { CorePushNotificationsDelegate } from '@core/pushnotifications/providers/delegate'; | import { CorePushNotificationsDelegate } from '@core/pushnotifications/providers/delegate'; | ||||||
| import { CoreEmulatorHelperProvider } from '@core/emulator/providers/helper'; | import { CoreEmulatorHelperProvider } from '@core/emulator/providers/helper'; | ||||||
|  | import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Handler to inject an option into main menu. |  * Handler to inject an option into main menu. | ||||||
| @ -49,7 +49,7 @@ export class AddonMessagesMainMenuHandler implements CoreMainMenuHandler, CoreCr | |||||||
| 
 | 
 | ||||||
|     constructor(private messagesProvider: AddonMessagesProvider, private sitesProvider: CoreSitesProvider, |     constructor(private messagesProvider: AddonMessagesProvider, private sitesProvider: CoreSitesProvider, | ||||||
|             eventsProvider: CoreEventsProvider, private appProvider: CoreAppProvider, |             eventsProvider: CoreEventsProvider, private appProvider: CoreAppProvider, | ||||||
|             private localNotificationsProvider: CoreLocalNotificationsProvider, private textUtils: CoreTextUtilsProvider, |             private localNotificationsProvider: CoreLocalNotificationsProvider, private filterHelper: CoreFilterHelperProvider, | ||||||
|             private pushNotificationsProvider: CorePushNotificationsProvider, utils: CoreUtilsProvider, |             private pushNotificationsProvider: CorePushNotificationsProvider, utils: CoreUtilsProvider, | ||||||
|             pushNotificationsDelegate: CorePushNotificationsDelegate, private emulatorHelper: CoreEmulatorHelperProvider) { |             pushNotificationsDelegate: CorePushNotificationsDelegate, private emulatorHelper: CoreEmulatorHelperProvider) { | ||||||
| 
 | 
 | ||||||
| @ -297,7 +297,7 @@ export class AddonMessagesMainMenuHandler implements CoreMainMenuHandler, CoreCr | |||||||
|             title: message.name || message.userfromfullname, |             title: message.name || message.userfromfullname, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         return this.textUtils.formatText(message.text, true, true).catch(() => { |         return this.filterHelper.getFiltersAndFormatText(message.text, 'system', 0, {clean: true, singleLine: true}).catch(() => { | ||||||
|             return message.text; |             return message.text; | ||||||
|         }).then((formattedText) => { |         }).then((formattedText) => { | ||||||
|             data['text'] = formattedText; |             data['text'] = formattedText; | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|                 {{ 'addon.mod_assign.feedbacknotsupported' | translate }} |                 {{ 'addon.mod_assign.feedbacknotsupported' | translate }} | ||||||
|             </ion-badge> |             </ion-badge> | ||||||
|             <p *ngIf="text"> |             <p *ngIf="text"> | ||||||
|                 <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text"></core-format-text> |                 <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid" [courseId]="assign.course"></core-format-text> | ||||||
|             </p> |             </p> | ||||||
|             <core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-file> |             <core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-file> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ | |||||||
|     <!-- Description and intro attachments. --> |     <!-- Description and intro attachments. --> | ||||||
|     <ion-card *ngIf="description" (click)="expandDescription($event)"> |     <ion-card *ngIf="description" (click)="expandDescription($event)"> | ||||||
|         <ion-item text-wrap> |         <ion-item text-wrap> | ||||||
|             <core-format-text [text]="description" [component]="component" [componentId]="componentId" maxHeight="120" (click)="expandDescription($event)"></core-format-text> |             <core-format-text [text]="description" [component]="component" [componentId]="componentId" maxHeight="120" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId" (click)="expandDescription($event)"></core-format-text> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|     </ion-card> |     </ion-card> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -134,7 +134,7 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo | |||||||
| 
 | 
 | ||||||
|         if (this.assign && (this.description || this.assign.introattachments)) { |         if (this.assign && (this.description || this.assign.introattachments)) { | ||||||
|             this.textUtils.expandText(this.translate.instant('core.description'), this.description, this.component, |             this.textUtils.expandText(this.translate.instant('core.description'), this.description, this.component, | ||||||
|                     this.module.id, this.assign.introattachments); |                     this.module.id, this.assign.introattachments, true, 'module', this.module.id, this.courseId); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
|                 {{ 'addon.mod_assign.submissionnotsupported' | translate }} |                 {{ 'addon.mod_assign.submissionnotsupported' | translate }} | ||||||
|             </ion-badge> |             </ion-badge> | ||||||
|             <p *ngIf="text"> |             <p *ngIf="text"> | ||||||
|                 <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text"></core-format-text> |                 <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid" [courseId]="assign.course"></core-format-text> | ||||||
|             </p> |             </p> | ||||||
|             <core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-file> |             <core-file *ngFor="let file of files" [file]="file" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-file> | ||||||
|         </ion-item> |         </ion-item> | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ | |||||||
| 
 | 
 | ||||||
|                 <ion-item text-wrap *ngIf="timeRemaining" [ngClass]="[timeRemainingClass]"> |                 <ion-item text-wrap *ngIf="timeRemaining" [ngClass]="[timeRemainingClass]"> | ||||||
|                     <h2>{{ 'addon.mod_assign.timeremaining' | translate }}</h2> |                     <h2>{{ 'addon.mod_assign.timeremaining' | translate }}</h2> | ||||||
|                     <p><core-format-text [text]="timeRemaining"></core-format-text></p> |                     <p [innerHTML]="timeRemaining"></p> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| 
 | 
 | ||||||
|                 <ion-item text-wrap *ngIf="fromDate && !isSubmittedForGrading"> |                 <ion-item text-wrap *ngIf="fromDate && !isSubmittedForGrading"> | ||||||
| @ -91,7 +91,7 @@ | |||||||
|                 <!-- Submit for grading form. --> |                 <!-- Submit for grading form. --> | ||||||
|                 <div *ngIf="canSubmit"> |                 <div *ngIf="canSubmit"> | ||||||
|                     <ion-item text-wrap *ngIf="submissionStatement"> |                     <ion-item text-wrap *ngIf="submissionStatement"> | ||||||
|                         <ion-label><core-format-text [text]="submissionStatement"></core-format-text></ion-label> |                         <ion-label><core-format-text [text]="submissionStatement" [filter]="false"></core-format-text></ion-label> | ||||||
|                         <ion-checkbox item-end name="submissionstatement" [(ngModel)]="submitModel.submissionStatement"> |                         <ion-checkbox item-end name="submissionstatement" [(ngModel)]="submitModel.submissionStatement"> | ||||||
|                         </ion-checkbox> |                         </ion-checkbox> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
| @ -115,7 +115,7 @@ | |||||||
|                             <h2>{{ user.fullname }}</h2> |                             <h2>{{ user.fullname }}</h2> | ||||||
|                         </a> |                         </a> | ||||||
|                         <ion-item text-wrap *ngIf="!user.fullname"> |                         <ion-item text-wrap *ngIf="!user.fullname"> | ||||||
|                             {{ 'addon.mod_assign.hiddenuser' | translate }} <core-format-text [text]="user"></core-format-text> |                             {{ 'addon.mod_assign.hiddenuser' | translate }} {{ user }} | ||||||
|                         </ion-item> |                         </ion-item> | ||||||
|                     </div> |                     </div> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
| @ -140,7 +140,7 @@ | |||||||
|                 <!-- Current grade if method is advanced. --> |                 <!-- Current grade if method is advanced. --> | ||||||
|                 <ion-item text-wrap *ngIf="feedback.gradefordisplay && (!isGrading || grade.method != 'simple')" class="core-grading-summary"> |                 <ion-item text-wrap *ngIf="feedback.gradefordisplay && (!isGrading || grade.method != 'simple')" class="core-grading-summary"> | ||||||
|                     <h2>{{ 'addon.mod_assign.currentgrade' | translate }}</h2> |                     <h2>{{ 'addon.mod_assign.currentgrade' | translate }}</h2> | ||||||
|                     <p><core-format-text [text]="feedback.gradefordisplay"></core-format-text></p> |                     <p><core-format-text [text]="feedback.gradefordisplay" [filter]="false"></core-format-text></p> | ||||||
|                     <a ion-button item-end icon-only *ngIf="feedback.advancedgrade" (click)="showAdvancedGrade()"> |                     <a ion-button item-end icon-only *ngIf="feedback.advancedgrade" (click)="showAdvancedGrade()"> | ||||||
|                         <ion-icon name="search"></ion-icon> |                         <ion-icon name="search"></ion-icon> | ||||||
|                     </a> |                     </a> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <ion-item text-wrap *ngIf="(text || canEdit) && !edit"> | <ion-item text-wrap *ngIf="(text || canEdit) && !edit"> | ||||||
|     <h2>{{ plugin.name }}</h2> |     <h2>{{ plugin.name }}</h2> | ||||||
|     <p> |     <p> | ||||||
|         <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text"></core-format-text> |         <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid" [courseId]="assign.course"></core-format-text> | ||||||
|     </p> |     </p> | ||||||
|     <div item-end> |     <div item-end> | ||||||
|         <div text-end> |         <div text-end> | ||||||
|  | |||||||
| @ -65,7 +65,8 @@ export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedb | |||||||
| 
 | 
 | ||||||
|                     if (this.text) { |                     if (this.text) { | ||||||
|                         // Open a new state with the text.
 |                         // Open a new state with the text.
 | ||||||
|                         this.textUtils.expandText(this.plugin.name, this.text, this.component, this.assign.cmid); |                         this.textUtils.expandText(this.plugin.name, this.text, this.component, this.assign.cmid, undefined, true, | ||||||
|  |                                 'module', this.assign.cmid, this.assign.course); | ||||||
|                     } |                     } | ||||||
|                 }); |                 }); | ||||||
|             } else if (this.edit) { |             } else if (this.edit) { | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="plugin.name"></core-format-text></ion-title> |         <ion-title>{{ plugin.name }}</ion-title> | ||||||
|         <ion-buttons end> |         <ion-buttons end> | ||||||
|             <button ion-button icon-only (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> |             <button ion-button icon-only (click)="closeModal()" [attr.aria-label]="'core.close' | translate"> | ||||||
|                 <ion-icon name="close"></ion-icon> |                 <ion-icon name="close"></ion-icon> | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title><core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"></core-format-text></ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons end> |         <ion-buttons end> | ||||||
|             <button ion-button clear (click)="save()" [attr.aria-label]="'core.save' | translate"> |             <button ion-button clear (click)="save()" [attr.aria-label]="'core.save' | translate"> | ||||||
| @ -16,7 +16,7 @@ | |||||||
|             <form name="addon-mod_assign-edit-form" *ngIf="userSubmission && userSubmission.plugins && userSubmission.plugins.length"> |             <form name="addon-mod_assign-edit-form" *ngIf="userSubmission && userSubmission.plugins && userSubmission.plugins.length"> | ||||||
|                 <!-- Submission statement. --> |                 <!-- Submission statement. --> | ||||||
|                 <ion-item text-wrap *ngIf="submissionStatement"> |                 <ion-item text-wrap *ngIf="submissionStatement"> | ||||||
|                     <ion-label><core-format-text [text]="submissionStatement"></core-format-text></ion-label> |                     <ion-label><core-format-text [text]="submissionStatement" [filter]="false"></core-format-text></ion-label> | ||||||
|                     <ion-checkbox item-end name="submissionstatement" [(ngModel)]="submissionStatementAccepted"></ion-checkbox> |                     <ion-checkbox item-end name="submissionstatement" [(ngModel)]="submissionStatementAccepted"></ion-checkbox> | ||||||
| 
 | 
 | ||||||
|                     <!-- ion-checkbox doesn't use an input. Create a hidden input to hold the value. --> |                     <!-- ion-checkbox doesn't use an input. Create a hidden input to hold the value. --> | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title><core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text></ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons end> |         <ion-buttons end> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title><core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId"  [courseId]="courseId"></core-format-text></ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons end></ion-buttons> |         <ion-buttons end></ion-buttons> | ||||||
|     </ion-navbar> |     </ion-navbar> | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title><core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"></core-format-text></ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons end></ion-buttons> |         <ion-buttons end></ion-buttons> | ||||||
|     </ion-navbar> |     </ion-navbar> | ||||||
|  | |||||||
| @ -31,6 +31,7 @@ import { AddonModAssignHelperProvider, AddonModAssignSubmissionFormatted } from | |||||||
| import { AddonModAssignSyncProvider } from './assign-sync'; | import { AddonModAssignSyncProvider } from './assign-sync'; | ||||||
| import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; | import { AddonModAssignFeedbackDelegate } from './feedback-delegate'; | ||||||
| import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | import { AddonModAssignSubmissionDelegate } from './submission-delegate'; | ||||||
|  | import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Handler to prefetch assigns. |  * Handler to prefetch assigns. | ||||||
| @ -42,16 +43,26 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
|     component = AddonModAssignProvider.COMPONENT; |     component = AddonModAssignProvider.COMPONENT; | ||||||
|     updatesNames = /^configuration$|^.*files$|^submissions$|^grades$|^gradeitems$|^outcomes$|^comments$/; |     updatesNames = /^configuration$|^.*files$|^submissions$|^grades$|^gradeitems$|^outcomes$|^comments$/; | ||||||
| 
 | 
 | ||||||
|     constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, |     constructor(translate: TranslateService, | ||||||
|             courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, |             appProvider: CoreAppProvider, | ||||||
|             domUtils: CoreDomUtilsProvider, protected assignProvider: AddonModAssignProvider, |             utils: CoreUtilsProvider, | ||||||
|             protected textUtils: CoreTextUtilsProvider, protected feedbackDelegate: AddonModAssignFeedbackDelegate, |             courseProvider: CoreCourseProvider, | ||||||
|             protected submissionDelegate: AddonModAssignSubmissionDelegate, protected courseHelper: CoreCourseHelperProvider, |             filepoolProvider: CoreFilepoolProvider, | ||||||
|             protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider, |             sitesProvider: CoreSitesProvider, | ||||||
|             protected userProvider: CoreUserProvider, protected assignHelper: AddonModAssignHelperProvider, |             domUtils: CoreDomUtilsProvider, | ||||||
|  |             filterHelper: CoreFilterHelperProvider, | ||||||
|  |             protected assignProvider: AddonModAssignProvider, | ||||||
|  |             protected textUtils: CoreTextUtilsProvider, | ||||||
|  |             protected feedbackDelegate: AddonModAssignFeedbackDelegate, | ||||||
|  |             protected submissionDelegate: AddonModAssignSubmissionDelegate, | ||||||
|  |             protected courseHelper: CoreCourseHelperProvider, | ||||||
|  |             protected groupsProvider: CoreGroupsProvider, | ||||||
|  |             protected gradesHelper: CoreGradesHelperProvider, | ||||||
|  |             protected userProvider: CoreUserProvider, | ||||||
|  |             protected assignHelper: AddonModAssignHelperProvider, | ||||||
|             protected syncProvider: AddonModAssignSyncProvider) { |             protected syncProvider: AddonModAssignSyncProvider) { | ||||||
| 
 | 
 | ||||||
|         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); |         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils, filterHelper); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| <a *ngIf="commentsEnabled" ion-item text-wrap (click)="showComments($event)" detail-none> | <a *ngIf="commentsEnabled" ion-item text-wrap (click)="showComments($event)" detail-none> | ||||||
|     <h2>{{plugin.name}}</h2> |     <h2>{{plugin.name}}</h2> | ||||||
|     <core-comments contextLevel="module" [instanceId]="assign.cmid" component="assignsubmission_comments" [itemId]="submission.id" area="submission_comments" [title]="plugin.name"></core-comments> |     <core-comments contextLevel="module" [instanceId]="assign.cmid" component="assignsubmission_comments" [itemId]="submission.id" area="submission_comments" [title]="plugin.name" [courseId]="assign.course"></core-comments> | ||||||
| </a> | </a> | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
|     <h2>{{ plugin.name }}</h2> |     <h2>{{ plugin.name }}</h2> | ||||||
|     <p *ngIf="words">{{ 'addon.mod_assign.numwords' | translate: {'$a': words} }}</p> |     <p *ngIf="words">{{ 'addon.mod_assign.numwords' | translate: {'$a': words} }}</p> | ||||||
|     <p> |     <p> | ||||||
|         <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text"></core-format-text> |         <core-format-text [component]="component" [componentId]="assign.cmid" [maxHeight]="80" [fullOnClick]="true" [fullTitle]="plugin.name" [text]="text" contextLevel="module" [contextInstanceId]="assign.cmid" [courseId]="assign.course"></core-format-text> | ||||||
|     </p> |     </p> | ||||||
| </ion-item> | </ion-item> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -75,7 +75,8 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS | |||||||
| 
 | 
 | ||||||
|                     if (text) { |                     if (text) { | ||||||
|                         // Open a new state with the interpolated contents.
 |                         // Open a new state with the interpolated contents.
 | ||||||
|                         this.textUtils.expandText(this.plugin.name, text, this.component, this.assign.cmid); |                         this.textUtils.expandText(this.plugin.name, text, this.component, this.assign.cmid, undefined, true, | ||||||
|  |                                 'module', this.assign.cmid, this.assign.course); | ||||||
|                     } |                     } | ||||||
|                 }); |                 }); | ||||||
|             } else { |             } else { | ||||||
|  | |||||||
| @ -16,11 +16,11 @@ | |||||||
| <!-- Content. --> | <!-- Content. --> | ||||||
| <core-loading [hideUntil]="loaded" class="core-loading-center"> | <core-loading [hideUntil]="loaded" class="core-loading-center"> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId"></core-course-module-description> |     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description> | ||||||
| 
 | 
 | ||||||
|     <div padding class="safe-padding-horizontal"> |     <div padding class="safe-padding-horizontal"> | ||||||
|         <core-navigation-bar [previous]="previousChapter > 0 && previousChapter" [next]="nextChapter > 0 && nextChapter" (action)="changeChapter($event)"></core-navigation-bar> |         <core-navigation-bar [previous]="previousChapter > 0 && previousChapter" [next]="nextChapter > 0 && nextChapter" (action)="changeChapter($event)"></core-navigation-bar> | ||||||
|         <core-format-text [component]="component" [componentId]="componentId" [text]="chapterContent"></core-format-text> |         <core-format-text [component]="component" [componentId]="componentId" [text]="chapterContent" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text> | ||||||
|         <div margin-top *ngIf="tagsEnabled && contentsMap && contentsMap[currentChapter] && contentsMap[currentChapter].tags && contentsMap[currentChapter].tags.length > 0"> |         <div margin-top *ngIf="tagsEnabled && contentsMap && contentsMap[currentChapter] && contentsMap[currentChapter].tags && contentsMap[currentChapter].tags.length > 0"> | ||||||
|             <b>{{ 'core.tag.tags' | translate }}:</b> |             <b>{{ 'core.tag.tags' | translate }}:</b> | ||||||
|             <core-tag-list [tags]="contentsMap[currentChapter].tags"></core-tag-list> |             <core-tag-list [tags]="contentsMap[currentChapter].tags"></core-tag-list> | ||||||
|  | |||||||
| @ -66,8 +66,10 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp | |||||||
|     showToc(event: MouseEvent): void { |     showToc(event: MouseEvent): void { | ||||||
|         // Create the toc modal.
 |         // Create the toc modal.
 | ||||||
|         const modal =  this.modalCtrl.create('AddonModBookTocPage', { |         const modal =  this.modalCtrl.create('AddonModBookTocPage', { | ||||||
|  |             moduleId: this.module.id, | ||||||
|             chapters: this.chapters, |             chapters: this.chapters, | ||||||
|             selected: this.currentChapter |             selected: this.currentChapter, | ||||||
|  |             courseId: this.courseId | ||||||
|         }, { cssClass: 'core-modal-lateral', |         }, { cssClass: 'core-modal-lateral', | ||||||
|             showBackdrop: true, |             showBackdrop: true, | ||||||
|             enableBackdropDismiss: true, |             enableBackdropDismiss: true, | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title><core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text></ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons end> |         <ion-buttons end> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ | |||||||
|     <nav> |     <nav> | ||||||
|         <ion-list> |         <ion-list> | ||||||
|             <a ion-item text-wrap *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)" [class.core-nav-item-selected]="selected == chapter.id" [class.item-dimmed]="chapter.hidden"> |             <a ion-item text-wrap *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)" [class.core-nav-item-selected]="selected == chapter.id" [class.item-dimmed]="chapter.hidden"> | ||||||
|                 <p [attr.padding-left]="chapter.level == 1 ? true : null">{{chapter.number}} {{chapter.title}}</p> |                 <p [attr.padding-left]="chapter.level == 1 ? true : null">{{chapter.number}} <core-format-text [text]="chapter.title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId"></core-format-text></p> | ||||||
|             </a> |             </a> | ||||||
|         </ion-list> |         </ion-list> | ||||||
|     </nav> |     </nav> | ||||||
|  | |||||||
| @ -25,12 +25,16 @@ import { AddonModBookTocChapter } from '../../providers/book'; | |||||||
|     templateUrl: 'toc.html' |     templateUrl: 'toc.html' | ||||||
| }) | }) | ||||||
| export class AddonModBookTocPage { | export class AddonModBookTocPage { | ||||||
|  |     moduleId: number; | ||||||
|     chapters: AddonModBookTocChapter[]; |     chapters: AddonModBookTocChapter[]; | ||||||
|     selected: number; |     selected: number; | ||||||
|  |     courseId: number; | ||||||
| 
 | 
 | ||||||
|     constructor(navParams: NavParams, private viewCtrl: ViewController) { |     constructor(navParams: NavParams, private viewCtrl: ViewController) { | ||||||
|  |         this.moduleId = navParams.get('moduleId'); | ||||||
|         this.chapters = navParams.get('chapters') || []; |         this.chapters = navParams.get('chapters') || []; | ||||||
|         this.selected = navParams.get('selected'); |         this.selected = navParams.get('selected'); | ||||||
|  |         this.courseId = navParams.get('courseId'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -22,6 +22,7 @@ import { CoreUtilsProvider } from '@providers/utils/utils'; | |||||||
| import { CoreCourseProvider } from '@core/course/providers/course'; | import { CoreCourseProvider } from '@core/course/providers/course'; | ||||||
| import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler'; | import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler'; | ||||||
| import { AddonModBookProvider } from './book'; | import { AddonModBookProvider } from './book'; | ||||||
|  | import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Handler to prefetch books. |  * Handler to prefetch books. | ||||||
| @ -33,11 +34,17 @@ export class AddonModBookPrefetchHandler extends CoreCourseResourcePrefetchHandl | |||||||
|     component = AddonModBookProvider.COMPONENT; |     component = AddonModBookProvider.COMPONENT; | ||||||
|     updatesNames = /^configuration$|^.*files$|^entries$/; |     updatesNames = /^configuration$|^.*files$|^entries$/; | ||||||
| 
 | 
 | ||||||
|     constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, |     constructor(translate: TranslateService, | ||||||
|             courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, |             appProvider: CoreAppProvider, | ||||||
|             domUtils: CoreDomUtilsProvider, protected bookProvider: AddonModBookProvider) { |             utils: CoreUtilsProvider, | ||||||
|  |             courseProvider: CoreCourseProvider, | ||||||
|  |             filepoolProvider: CoreFilepoolProvider, | ||||||
|  |             sitesProvider: CoreSitesProvider, | ||||||
|  |             domUtils: CoreDomUtilsProvider, | ||||||
|  |             filterHelper: CoreFilterHelperProvider, | ||||||
|  |             protected bookProvider: AddonModBookProvider) { | ||||||
| 
 | 
 | ||||||
|         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); |         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils, filterHelper); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ | |||||||
| <!-- Content. --> | <!-- Content. --> | ||||||
| <core-loading [hideUntil]="loaded" class="core-loading-center safe-area-page"> | <core-loading [hideUntil]="loaded" class="core-loading-center safe-area-page"> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId"></core-course-module-description> |     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description> | ||||||
| 
 | 
 | ||||||
|     <ion-card icon-start class="core-info-card" *ngIf="chatInfo"> |     <ion-card icon-start class="core-info-card" *ngIf="chatInfo"> | ||||||
|         <ion-icon name="time"></ion-icon> {{ 'addon.mod_chat.sessionstart' | translate:{$a: chatInfo} }} |         <ion-icon name="time"></ion-icon> {{ 'addon.mod_chat.sessionstart' | translate:{$a: chatInfo} }} | ||||||
|  | |||||||
| @ -95,7 +95,12 @@ export class AddonModChatIndexComponent extends CoreCourseModuleMainActivityComp | |||||||
|      */ |      */ | ||||||
|     enterChat(): void { |     enterChat(): void { | ||||||
|         const title = this.chat.name || this.moduleName; |         const title = this.chat.name || this.moduleName; | ||||||
|         this.navCtrl.push('AddonModChatChatPage', {chatId: this.chat.id, courseId: this.courseId, title: title }); |         this.navCtrl.push('AddonModChatChatPage', { | ||||||
|  |             chatId: this.chat.id, | ||||||
|  |             courseId: this.courseId, | ||||||
|  |             title: title, | ||||||
|  |             cmId: this.module.id | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title><core-format-text [text]="title" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"></core-format-text></ion-title> | ||||||
|         <ion-buttons end> |         <ion-buttons end> | ||||||
|             <button *ngIf="loaded" ion-button icon-only (click)="showChatUsers()"> |             <button *ngIf="loaded" ion-button icon-only (click)="showChatUsers()"> | ||||||
|                 <ion-icon name="people"></ion-icon> |                 <ion-icon name="people"></ion-icon> | ||||||
| @ -43,7 +43,7 @@ | |||||||
| 
 | 
 | ||||||
|                     <ion-badge text-wrap color="info" *ngIf="!message.system && !message.beep"> |                     <ion-badge text-wrap color="info" *ngIf="!message.system && !message.beep"> | ||||||
|                         <span><core-icon name="fa-asterisk"></core-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} |                         <span><core-icon name="fa-asterisk"></core-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} | ||||||
|                             <strong>{{ message.userfullname }} <core-format-text [text]="message.message" (afterRender)="last && scrollToBottom()"></core-format-text></strong></span> |                             <strong>{{ message.userfullname }} <core-format-text [text]="message.message" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId" (afterRender)="last && scrollToBottom()"></core-format-text></strong></span> | ||||||
|                     </ion-badge> |                     </ion-badge> | ||||||
|                 </div> |                 </div> | ||||||
| 
 | 
 | ||||||
| @ -56,7 +56,7 @@ | |||||||
|                     </h2> |                     </h2> | ||||||
| 
 | 
 | ||||||
|                     <p class="addon-message-text"> |                     <p class="addon-message-text"> | ||||||
|                         <core-format-text [text]="message.message" (afterRender)="last && scrollToBottom()"></core-format-text> |                         <core-format-text [text]="message.message" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId" (afterRender)="last && scrollToBottom()"></core-format-text> | ||||||
|                     </p> |                     </p> | ||||||
|                     <div class="tail" *ngIf="message.showTail"></div> |                     <div class="tail" *ngIf="message.showTail"></div> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|  | |||||||
| @ -46,6 +46,7 @@ export class AddonModChatChatPage { | |||||||
|     isOnline: boolean; |     isOnline: boolean; | ||||||
|     currentUserId: number; |     currentUserId: number; | ||||||
|     sending: boolean; |     sending: boolean; | ||||||
|  |     cmId: number; | ||||||
| 
 | 
 | ||||||
|     protected logger; |     protected logger; | ||||||
|     protected courseId: number; |     protected courseId: number; | ||||||
| @ -67,6 +68,8 @@ export class AddonModChatChatPage { | |||||||
|         this.chatId = navParams.get('chatId'); |         this.chatId = navParams.get('chatId'); | ||||||
|         this.courseId = navParams.get('courseId'); |         this.courseId = navParams.get('courseId'); | ||||||
|         this.title = navParams.get('title'); |         this.title = navParams.get('title'); | ||||||
|  |         this.cmId = navParams.get('cmId'); | ||||||
|  | 
 | ||||||
|         this.logger = logger.getInstance('AddonModChoiceChoicePage'); |         this.logger = logger.getInstance('AddonModChoiceChoicePage'); | ||||||
|         this.currentUserId = sitesProvider.getCurrentSiteUserId(); |         this.currentUserId = sitesProvider.getCurrentSiteUserId(); | ||||||
|         this.isOnline = this.appProvider.isOnline(); |         this.isOnline = this.appProvider.isOnline(); | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title><core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text></ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons end> |         <ion-buttons end> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -40,7 +40,7 @@ | |||||||
| 
 | 
 | ||||||
|                     <ion-badge text-wrap color="info" *ngIf="!message.issystem && !message.beep"> |                     <ion-badge text-wrap color="info" *ngIf="!message.issystem && !message.beep"> | ||||||
|                         <span><core-icon name="fa-asterisk"></core-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} |                         <span><core-icon name="fa-asterisk"></core-icon> {{ message.timestamp * 1000 | coreFormatDate:"strftimetime" }} | ||||||
|                             <strong>{{ message.userfullname }} <core-format-text [text]="message.message"></core-format-text></strong></span> |                             <strong>{{ message.userfullname }} <core-format-text [text]="message.message" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"></core-format-text></strong></span> | ||||||
|                     </ion-badge> |                     </ion-badge> | ||||||
|                 </div> |                 </div> | ||||||
| 
 | 
 | ||||||
| @ -53,7 +53,7 @@ | |||||||
|                     </h2> |                     </h2> | ||||||
| 
 | 
 | ||||||
|                     <p class="addon-message-text"> |                     <p class="addon-message-text"> | ||||||
|                         <core-format-text [text]="message.message"></core-format-text> |                         <core-format-text [text]="message.message" contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId"></core-format-text> | ||||||
|                     </p> |                     </p> | ||||||
|                     <div class="tail" *ngIf="message.showTail"></div> |                     <div class="tail" *ngIf="message.showTail"></div> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|  | |||||||
| @ -31,14 +31,15 @@ import { AddonModChatHelperProvider, AddonModChatSessionMessageForView } from '. | |||||||
| export class AddonModChatSessionMessagesPage { | export class AddonModChatSessionMessagesPage { | ||||||
| 
 | 
 | ||||||
|     currentUserId: number; |     currentUserId: number; | ||||||
|  |     cmId: number; | ||||||
|  |     messages: AddonModChatSessionMessageForView[] = []; | ||||||
|  |     loaded = false; | ||||||
| 
 | 
 | ||||||
|     protected courseId: number; |     protected courseId: number; | ||||||
|     protected chatId: number; |     protected chatId: number; | ||||||
|     protected sessionStart: number; |     protected sessionStart: number; | ||||||
|     protected sessionEnd: number; |     protected sessionEnd: number; | ||||||
|     protected groupId: number; |     protected groupId: number; | ||||||
|     protected loaded = false; |  | ||||||
|     protected messages: AddonModChatSessionMessageForView[] = []; |  | ||||||
| 
 | 
 | ||||||
|     constructor(navParams: NavParams, private domUtils: CoreDomUtilsProvider, private chatProvider: AddonModChatProvider, |     constructor(navParams: NavParams, private domUtils: CoreDomUtilsProvider, private chatProvider: AddonModChatProvider, | ||||||
|         sitesProvider: CoreSitesProvider, private chatHelper: AddonModChatHelperProvider, private userProvider: CoreUserProvider) { |         sitesProvider: CoreSitesProvider, private chatHelper: AddonModChatHelperProvider, private userProvider: CoreUserProvider) { | ||||||
| @ -47,6 +48,7 @@ export class AddonModChatSessionMessagesPage { | |||||||
|         this.groupId = navParams.get('groupId'); |         this.groupId = navParams.get('groupId'); | ||||||
|         this.sessionStart = navParams.get('sessionStart'); |         this.sessionStart = navParams.get('sessionStart'); | ||||||
|         this.sessionEnd = navParams.get('sessionEnd'); |         this.sessionEnd = navParams.get('sessionEnd'); | ||||||
|  |         this.cmId = navParams.get('cmId'); | ||||||
|         this.currentUserId = sitesProvider.getCurrentSiteUserId(); |         this.currentUserId = sitesProvider.getCurrentSiteUserId(); | ||||||
| 
 | 
 | ||||||
|         this.fetchMessages(); |         this.fetchMessages(); | ||||||
|  | |||||||
| @ -140,7 +140,8 @@ export class AddonModChatSessionsPage { | |||||||
|             chatId: this.chatId, |             chatId: this.chatId, | ||||||
|             groupId: this.groupId, |             groupId: this.groupId, | ||||||
|             sessionStart: session.sessionstart, |             sessionStart: session.sessionstart, | ||||||
|             sessionEnd: session.sessionend |             sessionEnd: session.sessionend, | ||||||
|  |             cmId: this.cmId | ||||||
|         }; |         }; | ||||||
|         this.splitviewCtrl.push('AddonModChatSessionMessagesPage', params); |         this.splitviewCtrl.push('AddonModChatSessionMessagesPage', params); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ | |||||||
|     <core-loading [hideUntil]="usersLoaded"> |     <core-loading [hideUntil]="usersLoaded"> | ||||||
|         <ion-item text-wrap *ngFor="let user of users" [class.addon-mod-chat-user]="currentUserId != user.id && isOnline"> |         <ion-item text-wrap *ngFor="let user of users" [class.addon-mod-chat-user]="currentUserId != user.id && isOnline"> | ||||||
|             <ion-avatar core-user-avatar [user]="user" item-start></ion-avatar> |             <ion-avatar core-user-avatar [user]="user" item-start></ion-avatar> | ||||||
|             <h2><core-format-text [text]="user.fullname"></core-format-text></h2> |             <h2>{{ user.fullname }}</h2> | ||||||
|             <ng-container *ngIf="currentUserId != user.id && isOnline"> |             <ng-container *ngIf="currentUserId != user.id && isOnline"> | ||||||
|                 <button ion-button clear icon-left (click)="talkTo(user)"> |                 <button ion-button clear icon-left (click)="talkTo(user)"> | ||||||
|                     <ion-icon name="chatboxes"></ion-icon> |                     <ion-icon name="chatboxes"></ion-icon> | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ import { CoreCourseProvider } from '@core/course/providers/course'; | |||||||
| import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; | import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; | ||||||
| import { CoreUserProvider } from '@core/user/providers/user'; | import { CoreUserProvider } from '@core/user/providers/user'; | ||||||
| import { AddonModChatProvider, AddonModChatChat } from './chat'; | import { AddonModChatProvider, AddonModChatChat } from './chat'; | ||||||
|  | import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Handler to prefetch chats. |  * Handler to prefetch chats. | ||||||
| @ -41,11 +42,12 @@ export class AddonModChatPrefetchHandler extends CoreCourseActivityPrefetchHandl | |||||||
|             filepoolProvider: CoreFilepoolProvider, |             filepoolProvider: CoreFilepoolProvider, | ||||||
|             sitesProvider: CoreSitesProvider, |             sitesProvider: CoreSitesProvider, | ||||||
|             domUtils: CoreDomUtilsProvider, |             domUtils: CoreDomUtilsProvider, | ||||||
|  |             filterHelper: CoreFilterHelperProvider, | ||||||
|             private groupsProvider: CoreGroupsProvider, |             private groupsProvider: CoreGroupsProvider, | ||||||
|             private userProvider: CoreUserProvider, |             private userProvider: CoreUserProvider, | ||||||
|             private chatProvider: AddonModChatProvider) { |             private chatProvider: AddonModChatProvider) { | ||||||
| 
 | 
 | ||||||
|         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); |         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils, filterHelper); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ | |||||||
| <!-- Content. --> | <!-- Content. --> | ||||||
| <core-loading [hideUntil]="loaded" class="core-loading-center"> | <core-loading [hideUntil]="loaded" class="core-loading-center"> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId"></core-course-module-description> |     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description> | ||||||
| 
 | 
 | ||||||
|     <!-- Activity availability messages --> |     <!-- Activity availability messages --> | ||||||
|     <ion-card class="core-info-card" icon-start *ngIf="choiceNotOpenYet"> |     <ion-card class="core-info-card" icon-start *ngIf="choiceNotOpenYet"> | ||||||
| @ -24,7 +24,7 @@ | |||||||
|     </ion-card> |     </ion-card> | ||||||
|     <ion-card class="core-info-card" icon-start *ngIf="choiceClosed"> |     <ion-card class="core-info-card" icon-start *ngIf="choiceClosed"> | ||||||
|         <ion-icon name="information-circle"></ion-icon> |         <ion-icon name="information-circle"></ion-icon> | ||||||
|         <p *ngIf="options && options.length">{{ 'addon.mod_choice.yourselection' | translate }} <core-format-text [text]="options[0].text"></core-format-text></p> |         <p *ngIf="options && options.length">{{ 'addon.mod_choice.yourselection' | translate }} <core-format-text [text]="options[0].text" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text></p> | ||||||
|         <p>{{ 'addon.mod_choice.expired' | translate:{$a: closeTimeReadable} }}</p> |         <p>{{ 'addon.mod_choice.expired' | translate:{$a: closeTimeReadable} }}</p> | ||||||
|     </ion-card> |     </ion-card> | ||||||
| 
 | 
 | ||||||
| @ -43,13 +43,13 @@ | |||||||
|     <ion-card *ngIf="options && options.length"> |     <ion-card *ngIf="options && options.length"> | ||||||
|         <ng-container *ngIf="choice.allowmultiple"> |         <ng-container *ngIf="choice.allowmultiple"> | ||||||
|             <ion-item text-wrap *ngFor="let option of options"> |             <ion-item text-wrap *ngFor="let option of options"> | ||||||
|                 <ion-label><core-format-text [text]="option.text"></core-format-text> <span *ngIf="choice.limitanswers && option.countanswers >= option.maxanswers">{{ 'addon.mod_choice.full' | translate }}</span></ion-label> |                 <ion-label><core-format-text [text]="option.text" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text> <span *ngIf="choice.limitanswers && option.countanswers >= option.maxanswers">{{ 'addon.mod_choice.full' | translate }}</span></ion-label> | ||||||
|                 <ion-checkbox item-end [(ngModel)]="option.checked" [disabled]="option.disabled || !canEdit"></ion-checkbox> |                 <ion-checkbox item-end [(ngModel)]="option.checked" [disabled]="option.disabled || !canEdit"></ion-checkbox> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ng-container> |         </ng-container> | ||||||
|         <ng-container *ngIf="!choice.allowmultiple"> |         <ng-container *ngIf="!choice.allowmultiple"> | ||||||
|             <ion-item text-wrap *ngFor="let option of options" radio-group [(ngModel)]="selectedOption.id"> |             <ion-item text-wrap *ngFor="let option of options" radio-group [(ngModel)]="selectedOption.id"> | ||||||
|                 <ion-label><core-format-text [text]="option.text"></core-format-text> <span *ngIf="choice.limitanswers && option.countanswers >= option.maxanswers">{{ 'addon.mod_choice.full' | translate }}</span></ion-label> |                 <ion-label><core-format-text [text]="option.text" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text> <span *ngIf="choice.limitanswers && option.countanswers >= option.maxanswers">{{ 'addon.mod_choice.full' | translate }}</span></ion-label> | ||||||
|                 <ion-radio color="primary" [value]="option.id" [disabled]="option.disabled || !canEdit"></ion-radio> |                 <ion-radio color="primary" [value]="option.id" [disabled]="option.disabled || !canEdit"></ion-radio> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|         </ng-container> |         </ng-container> | ||||||
| @ -73,13 +73,13 @@ | |||||||
|                         <ion-icon item-start name="warning" color="warning"></ion-icon> {{ 'addon.mod_choice.resultsnotsynced' | translate }} |                         <ion-icon item-start name="warning" color="warning"></ion-icon> {{ 'addon.mod_choice.resultsnotsynced' | translate }} | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                     <ion-item> |                     <ion-item> | ||||||
|                         <core-chart type="pie" [data]="data" [labels]="labels" height="300"></core-chart> |                         <core-chart type="pie" [data]="data" [labels]="labels" height="300" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-chart> | ||||||
|                     </ion-item> |                     </ion-item> | ||||||
|                 </ion-col> |                 </ion-col> | ||||||
|                 <ion-col *ngIf="choice.publish && results" col-12 col-lg-7> |                 <ion-col *ngIf="choice.publish && results" col-12 col-lg-7> | ||||||
|                     <ion-item-group *ngFor="let result of results"> |                     <ion-item-group *ngFor="let result of results"> | ||||||
|                         <ion-item-divider text-wrap> |                         <ion-item-divider text-wrap> | ||||||
|                             <h2><core-format-text [text]="result.text"></core-format-text></h2> |                             <h2><core-format-text [text]="result.text" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text></h2> | ||||||
|                             <p>{{ 'addon.mod_choice.numberofuser' | translate }}: {{ result.numberofuser }} ({{ 'core.percentagenumber' | translate: {$a: result.percentageamountfixed} }})</p> |                             <p>{{ 'addon.mod_choice.numberofuser' | translate }}: {{ result.numberofuser }} ({{ 'core.percentagenumber' | translate: {$a: result.percentageamountfixed} }})</p> | ||||||
|                         </ion-item-divider> |                         </ion-item-divider> | ||||||
|                         <a ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseid" [userId]="user.userid" [title]="user.fullname" text-wrap> |                         <a ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseid" [userId]="user.userid" [title]="user.fullname" text-wrap> | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| <ion-header> | <ion-header> | ||||||
|     <ion-navbar core-back-button> |     <ion-navbar core-back-button> | ||||||
|         <ion-title><core-format-text [text]="title"></core-format-text></ion-title> |         <ion-title><core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text></ion-title> | ||||||
| 
 | 
 | ||||||
|         <ion-buttons end> |         <ion-buttons end> | ||||||
|             <!-- The buttons defined by the component will be added in here. --> |             <!-- The buttons defined by the component will be added in here. --> | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/acti | |||||||
| import { CoreUserProvider } from '@core/user/providers/user'; | import { CoreUserProvider } from '@core/user/providers/user'; | ||||||
| import { AddonModChoiceSyncProvider } from './sync'; | import { AddonModChoiceSyncProvider } from './sync'; | ||||||
| import { AddonModChoiceProvider } from './choice'; | import { AddonModChoiceProvider } from './choice'; | ||||||
|  | import { CoreFilterHelperProvider } from '@core/filter/providers/helper'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Handler to prefetch choices. |  * Handler to prefetch choices. | ||||||
| @ -37,12 +38,19 @@ export class AddonModChoicePrefetchHandler extends CoreCourseActivityPrefetchHan | |||||||
| 
 | 
 | ||||||
|     protected syncProvider: AddonModChoiceSyncProvider; // It will be injected later to prevent circular dependencies.
 |     protected syncProvider: AddonModChoiceSyncProvider; // It will be injected later to prevent circular dependencies.
 | ||||||
| 
 | 
 | ||||||
|     constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, |     constructor(translate: TranslateService, | ||||||
|             courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, |             appProvider: CoreAppProvider, | ||||||
|             domUtils: CoreDomUtilsProvider, protected choiceProvider: AddonModChoiceProvider, |             utils: CoreUtilsProvider, | ||||||
|             protected userProvider: CoreUserProvider, protected injector: Injector) { |             courseProvider: CoreCourseProvider, | ||||||
|  |             filepoolProvider: CoreFilepoolProvider, | ||||||
|  |             sitesProvider: CoreSitesProvider, | ||||||
|  |             domUtils: CoreDomUtilsProvider, | ||||||
|  |             filterHelper: CoreFilterHelperProvider, | ||||||
|  |             protected choiceProvider: AddonModChoiceProvider, | ||||||
|  |             protected userProvider: CoreUserProvider, | ||||||
|  |             protected injector: Injector) { | ||||||
| 
 | 
 | ||||||
|         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); |         super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils, filterHelper); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -22,15 +22,15 @@ | |||||||
|     <ion-icon name="thumbs-down"></ion-icon> |     <ion-icon name="thumbs-down"></ion-icon> | ||||||
| </a> | </a> | ||||||
| 
 | 
 | ||||||
| <core-comments *ngIf="action == 'comments' && mode == 'list'" contextLevel="module" [instanceId]="database.coursemodule" component="mod_data" [itemId]="entry.id" area="database_entry"></core-comments> | <core-comments *ngIf="action == 'comments' && mode == 'list'" contextLevel="module" [instanceId]="database.coursemodule" component="mod_data" [itemId]="entry.id" area="database_entry" [courseId]="database.course"></core-comments> | ||||||
| 
 | 
 | ||||||
| <span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 |  coreFormatDate }}</span> | <span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 |  coreFormatDate }}</span> | ||||||
| <span *ngIf="action == 'timemodified'">{{ entry.timemodified * 1000 |  coreFormatDate }}</span> | <span *ngIf="action == 'timemodified'">{{ entry.timemodified * 1000 |  coreFormatDate }}</span> | ||||||
| 
 | 
 | ||||||
| <a *ngIf="action == 'userpicture'" core-user-link [courseId]="database.courseid" [userId]="entry.userid" [title]="entry.fullname"> | <a *ngIf="action == 'userpicture'" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname"> | ||||||
|     <img class="avatar-round" [src]="userPicture" [alt]="'core.pictureof' | translate:{$a: entry.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'" role="presentation"> |     <img class="avatar-round" [src]="userPicture" [alt]="'core.pictureof' | translate:{$a: entry.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'" role="presentation"> | ||||||
| </a> | </a> | ||||||
| 
 | 
 | ||||||
| <a *ngIf="action == 'user' && entry" core-user-link [courseId]="database.courseid" [userId]="entry.userid" [title]="entry.fullname">{{entry.fullname}}</a> | <a *ngIf="action == 'user' && entry" core-user-link [courseId]="database.course" [userId]="entry.userid" [title]="entry.fullname">{{entry.fullname}}</a> | ||||||
| 
 | 
 | ||||||
| <core-tag-list *ngIf="tagsEnabled && action == 'tags' && entry" [tags]="entry.tags"></core-tag-list> | <core-tag-list *ngIf="tagsEnabled && action == 'tags' && entry" [tags]="entry.tags"></core-tag-list> | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ | |||||||
| <!-- Content. --> | <!-- Content. --> | ||||||
| <core-loading [hideUntil]="loaded" class="core-loading-center"> | <core-loading [hideUntil]="loaded" class="core-loading-center"> | ||||||
| 
 | 
 | ||||||
|     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId"></core-course-module-description> |     <core-course-module-description [description]="description" [component]="component" [componentId]="componentId" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-course-module-description> | ||||||
| 
 | 
 | ||||||
|     <!-- Data done in offline but not synchronized --> |     <!-- Data done in offline but not synchronized --> | ||||||
|     <div class="core-warning-card" icon-start *ngIf="hasOffline || hasOfflineRatings"> |     <div class="core-warning-card" icon-start *ngIf="hasOffline || hasOfflineRatings"> | ||||||
|  | |||||||
| @ -12,4 +12,4 @@ | |||||||
|     </ion-item> |     </ion-item> | ||||||
| </span> | </span> | ||||||
| 
 | 
 | ||||||
| <core-format-text *ngIf="isShowOrListMode() && value && value.content" [text]="value.content"></core-format-text> | <core-format-text *ngIf="isShowOrListMode() && value && value.content" [text]="value.content" [filter]="false"></core-format-text> | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user