forked from CIT/Vmeda.Online
		
	MOBILE-3752 lint: Remove duplicated spaces
This commit is contained in:
		
							parent
							
								
									5d20d4faa7
								
							
						
					
					
						commit
						2a1e8a44e8
					
				@ -12,11 +12,11 @@
 | 
			
		||||
            <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
			
		||||
        </ion-refresher>
 | 
			
		||||
        <core-loading [hideUntil]="badges.loaded">
 | 
			
		||||
            <core-empty-box *ngIf="badges.empty"  icon="fas-trophy"
 | 
			
		||||
            <core-empty-box *ngIf="badges.empty" icon="fas-trophy"
 | 
			
		||||
                [message]="'addon.badges.nobadges' | translate">
 | 
			
		||||
            </core-empty-box>
 | 
			
		||||
 | 
			
		||||
            <ion-list *ngIf="!badges.empty"  class="ion-no-margin">
 | 
			
		||||
            <ion-list *ngIf="!badges.empty" class="ion-no-margin">
 | 
			
		||||
                <ion-item button class="ion-text-wrap" *ngFor="let badge of badges.items" [attr.aria-label]="badge.name"
 | 
			
		||||
                    (click)="badges.select(badge)" [attr.aria-current]="badges.getItemAriaCurrent(badge)">
 | 
			
		||||
                    <ion-avatar slot="start">
 | 
			
		||||
 | 
			
		||||
@ -327,8 +327,8 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
 | 
			
		||||
    /**
 | 
			
		||||
     * Helper function to help with filter values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  showCondition     If true, filter will be shown.
 | 
			
		||||
     * @param  disabledCondition If true, and showCondition is also met, it will be shown as disabled.
 | 
			
		||||
     * @param showCondition     If true, filter will be shown.
 | 
			
		||||
     * @param disabledCondition If true, and showCondition is also met, it will be shown as disabled.
 | 
			
		||||
     * @return                   show / disabled / hidden value.
 | 
			
		||||
     */
 | 
			
		||||
    protected getShowFilterValue(showCondition: boolean, disabledCondition: boolean): string {
 | 
			
		||||
@ -507,7 +507,7 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
 | 
			
		||||
        courses.forEach((course) => {
 | 
			
		||||
            if (course.hidden) {
 | 
			
		||||
                this.courses.hidden.push(course);
 | 
			
		||||
            } else  {
 | 
			
		||||
            } else {
 | 
			
		||||
                this.courses.all.push(course);
 | 
			
		||||
 | 
			
		||||
                if ((course.enddate && course.enddate < today) || course.completed) {
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ import { CoreBlockBaseHandler } from '@features/block/classes/base-block-handler
 | 
			
		||||
import { makeSingleton } from '@singletons';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Block  handler.
 | 
			
		||||
 * Block handler.
 | 
			
		||||
 */
 | 
			
		||||
@Injectable({ providedIn: 'root' })
 | 
			
		||||
export class AddonBlockMyOverviewHandlerService extends CoreBlockBaseHandler {
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,8 @@
 | 
			
		||||
 | 
			
		||||
    .addon-calendar-navigation {
 | 
			
		||||
        padding-top: 5px;
 | 
			
		||||
        padding-left:  10px;
 | 
			
		||||
        padding-right:  10px;
 | 
			
		||||
        padding-left: 10px;
 | 
			
		||||
        padding-right: 10px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .addon-calendar-months {
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
    <core-empty-box *ngIf="!filteredEvents || !filteredEvents.length" icon="fas-calendar" [message]="'addon.calendar.noevents' | translate">
 | 
			
		||||
    </core-empty-box>
 | 
			
		||||
 | 
			
		||||
    <ion-list *ngIf="filteredEvents && filteredEvents.length"  class="ion-no-margin">
 | 
			
		||||
    <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
 | 
			
		||||
        <ng-container *ngFor="let event of filteredEvents">
 | 
			
		||||
            <ion-item class="ion-text-wrap addon-calendar-event" [attr.aria-label]="event.name" (click)="eventClicked(event)" button
 | 
			
		||||
                [ngClass]="['addon-calendar-eventtype-'+event.eventtype]">
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
                <core-context-menu-item *ngIf="!isCurrentDay" [priority]="900" [content]="'addon.calendar.today' | translate"
 | 
			
		||||
                    iconAction="fas-calendar-day" (action)="goToCurrentDay()">
 | 
			
		||||
                </core-context-menu-item>
 | 
			
		||||
                <core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline"  [priority]="400"
 | 
			
		||||
                <core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400"
 | 
			
		||||
                    [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event)"
 | 
			
		||||
                    [iconAction]="syncIcon" [closeOnClick]="false">
 | 
			
		||||
                </core-context-menu-item>
 | 
			
		||||
@ -57,7 +57,7 @@
 | 
			
		||||
            [message]="'addon.calendar.noevents' | translate">
 | 
			
		||||
        </core-empty-box>
 | 
			
		||||
 | 
			
		||||
        <ion-list *ngIf="filteredEvents && filteredEvents.length"  class="ion-no-margin">
 | 
			
		||||
        <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
 | 
			
		||||
            <ng-container *ngFor="let event of filteredEvents">
 | 
			
		||||
                <ion-item class="addon-calendar-event ion-text-wrap" [attr.aria-label]="event.name" (click)="gotoEvent(event.id)"
 | 
			
		||||
                [class.item-dimmed]="event.ispast" [ngClass]="['addon-calendar-eventtype-'+event.eventtype]" button>
 | 
			
		||||
 | 
			
		||||
@ -531,7 +531,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave {
 | 
			
		||||
 | 
			
		||||
                try {
 | 
			
		||||
                    await AddonCalendarHelper.refreshAfterChangeEvent(result.event, numberOfRepetitions);
 | 
			
		||||
                } catch  {
 | 
			
		||||
                } catch {
 | 
			
		||||
                    // Ignore errors.
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -145,7 +145,7 @@
 | 
			
		||||
                </ion-label>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
            <ng-container *ngFor="let reminder of reminders">
 | 
			
		||||
                <ion-item  *ngIf="reminder.time > 0 || defaultTime > 0" class="ion-text-wrap"
 | 
			
		||||
                <ion-item *ngIf="reminder.time > 0 || defaultTime > 0" class="ion-text-wrap"
 | 
			
		||||
                    [class.item-dimmed]="(reminder.time == -1 ? (event.timestart - defaultTime) : reminder.time) <= currentTime!">
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <p *ngIf="reminder.time == -1">
 | 
			
		||||
 | 
			
		||||
@ -343,8 +343,8 @@ export class AddonCalendarEventPage implements OnInit, OnDestroy {
 | 
			
		||||
            const minute = Math.floor(currentTime / 60) * 60;
 | 
			
		||||
 | 
			
		||||
            // Check if the notification time is in the same minute as we are, so the notification is triggered.
 | 
			
		||||
            if (notificationTime >=  minute && notificationTime < minute + 60) {
 | 
			
		||||
                notificationTime  = currentTime + 1;
 | 
			
		||||
            if (notificationTime >= minute && notificationTime < minute + 60) {
 | 
			
		||||
                notificationTime = currentTime + 1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await AddonCalendar.addEventReminder(this.event, notificationTime);
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@
 | 
			
		||||
                <core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
 | 
			
		||||
                [content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs">
 | 
			
		||||
                </core-context-menu-item>
 | 
			
		||||
                <core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline"  [priority]="400"
 | 
			
		||||
                <core-context-menu-item [hidden]="!loaded || !hasOffline || !isOnline" [priority]="400"
 | 
			
		||||
                [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
 | 
			
		||||
                [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
 | 
			
		||||
            </core-context-menu>
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
                <core-context-menu-item [hidden]="!notificationsEnabled" [priority]="600"
 | 
			
		||||
                [content]="'core.settings.settings' | translate" (action)="openSettings()" iconAction="fas-cogs">
 | 
			
		||||
            </core-context-menu-item>
 | 
			
		||||
                <core-context-menu-item [hidden]="!eventsLoaded || !hasOffline || !isOnline"  [priority]="400"
 | 
			
		||||
                <core-context-menu-item [hidden]="!eventsLoaded || !hasOffline || !isOnline" [priority]="400"
 | 
			
		||||
                [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(undefined, $event, true)"
 | 
			
		||||
                [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
 | 
			
		||||
            </core-context-menu>
 | 
			
		||||
@ -37,7 +37,7 @@
 | 
			
		||||
                [message]="'addon.calendar.noevents' | translate">
 | 
			
		||||
            </core-empty-box>
 | 
			
		||||
 | 
			
		||||
            <ion-list *ngIf="filteredEvents && filteredEvents.length"  class="ion-no-margin">
 | 
			
		||||
            <ion-list *ngIf="filteredEvents && filteredEvents.length" class="ion-no-margin">
 | 
			
		||||
                <ng-container *ngFor="let event of filteredEvents">
 | 
			
		||||
                    <ion-item-divider *ngIf="event.showDate">
 | 
			
		||||
                        <ion-label><h2>{{ event.timestart * 1000 | coreFormatDate: "strftimedayshort" }}</h2></ion-label>
 | 
			
		||||
 | 
			
		||||
@ -476,7 +476,7 @@ export class AddonCalendarHelperProvider {
 | 
			
		||||
 | 
			
		||||
        const categoryId = filter.categoryId ? Number(filter.categoryId) : undefined;
 | 
			
		||||
 | 
			
		||||
        return  events.filter((event) => filter[event.formattedType] &&
 | 
			
		||||
        return events.filter((event) => filter[event.formattedType] &&
 | 
			
		||||
                this.shouldDisplayEvent(event, categories, courseId, categoryId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -203,7 +203,7 @@ export class AddonCalendarSyncProvider extends CoreSyncBaseProvider<AddonCalenda
 | 
			
		||||
                        id: event.id,
 | 
			
		||||
                        repeatid: event.repeatid,
 | 
			
		||||
                        timestart: event.timestart,
 | 
			
		||||
                        repeated:  data?.repeat ? (event as AddonCalendarEvent).eventcount || 1 : 1,
 | 
			
		||||
                        repeated: data?.repeat ? (event as AddonCalendarEvent).eventcount || 1 : 1,
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
@ -577,7 +577,7 @@ export class AddonCalendarProvider {
 | 
			
		||||
            value = site.getStoredConfig('calendar_lookahead');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return  parseInt(value as string, 10);
 | 
			
		||||
        return parseInt(value as string, 10);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -1595,7 +1595,7 @@ export class AddonCalendarProvider {
 | 
			
		||||
     * @param siteId ID of the site the event belongs to. If not defined, use current site.
 | 
			
		||||
     * @return Promise resolved when stored.
 | 
			
		||||
     */
 | 
			
		||||
    async storeEventInLocalDb(event:  AddonCalendarGetEventsEvent | AddonCalendarCalendarEvent, siteId?: string): Promise<void> {
 | 
			
		||||
    async storeEventInLocalDb(event: AddonCalendarGetEventsEvent | AddonCalendarCalendarEvent, siteId?: string): Promise<void> {
 | 
			
		||||
        const site = await CoreSites.getSite(siteId);
 | 
			
		||||
        siteId = site.getId();
 | 
			
		||||
        try {
 | 
			
		||||
@ -1775,7 +1775,7 @@ export const AddonCalendar = makeSingleton(AddonCalendarProvider);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Data returned by calendar's events_exporter.
 | 
			
		||||
 *  Data returned by core_calendar_get_action_events_by_course and core_calendar_get_action_events_by_timesort WS.
 | 
			
		||||
 * Data returned by core_calendar_get_action_events_by_course and core_calendar_get_action_events_by_timesort WS.
 | 
			
		||||
 */
 | 
			
		||||
export type AddonCalendarEvents = {
 | 
			
		||||
    events: AddonCalendarEvent[]; // Events.
 | 
			
		||||
@ -1912,7 +1912,7 @@ export type AddonCalendarEventBase = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Data returned by calendar's event_exporter.  Don't confuse it with AddonCalendarCalendarEvent.
 | 
			
		||||
 * Data returned by calendar's event_exporter. Don't confuse it with AddonCalendarCalendarEvent.
 | 
			
		||||
 */
 | 
			
		||||
export type AddonCalendarEvent = AddonCalendarEventBase & {
 | 
			
		||||
    url: string; // Url.
 | 
			
		||||
 | 
			
		||||
@ -98,7 +98,7 @@
 | 
			
		||||
                    <ion-badge slot="end" color="success" *ngIf="userCompetency.proficiency">
 | 
			
		||||
                        {{ 'core.yes' | translate }}
 | 
			
		||||
                    </ion-badge>
 | 
			
		||||
                    <ion-badge  slot="end" color="danger" *ngIf="!userCompetency.proficiency">
 | 
			
		||||
                    <ion-badge slot="end" color="danger" *ngIf="!userCompetency.proficiency">
 | 
			
		||||
                        {{ 'core.no' | translate }}
 | 
			
		||||
                    </ion-badge>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
@ -112,8 +112,8 @@
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
        <div *ngIf="competency">
 | 
			
		||||
            <h3  class="ion-margin-horizontal">{{ 'addon.competency.evidence' | translate }}</h3>
 | 
			
		||||
            <p  class="ion-margin-horizontal" *ngIf="competency.evidence.length == 0">
 | 
			
		||||
            <h3 class="ion-margin-horizontal">{{ 'addon.competency.evidence' | translate }}</h3>
 | 
			
		||||
            <p class="ion-margin-horizontal" *ngIf="competency.evidence.length == 0">
 | 
			
		||||
                {{ 'addon.competency.noevidence' | translate }}
 | 
			
		||||
            </p>
 | 
			
		||||
            <ion-card *ngFor="let evidence of competency.evidence">
 | 
			
		||||
@ -128,7 +128,7 @@
 | 
			
		||||
                <ion-item class="ion-text-wrap">
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <p><ion-badge color="dark">{{ evidence.gradename }}</ion-badge></p>
 | 
			
		||||
                        <p  class="ion-margin-top" *ngIf="evidence.description">{{ evidence.description }}</p>
 | 
			
		||||
                        <p class="ion-margin-top" *ngIf="evidence.description">{{ evidence.description }}</p>
 | 
			
		||||
                        <blockquote *ngIf="evidence.note">{{ evidence.note }}</blockquote>
 | 
			
		||||
                    </ion-label>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,7 @@
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
        <h3  class="ion-margin-horizontal" *ngIf="competencies && competencies.statistics.competencycount > 0">
 | 
			
		||||
        <h3 class="ion-margin-horizontal" *ngIf="competencies && competencies.statistics.competencycount > 0">
 | 
			
		||||
            {{ 'addon.competency.coursecompetencies' | translate }}
 | 
			
		||||
        </h3>
 | 
			
		||||
        <ion-card *ngIf="user">
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@
 | 
			
		||||
            <core-empty-box *ngIf="plans.empty" icon="fas-route" [message]="'addon.competency.noplanswerecreated' | translate">
 | 
			
		||||
 | 
			
		||||
            </core-empty-box>
 | 
			
		||||
            <ion-list *ngIf="!plans.empty"  class="ion-no-margin">
 | 
			
		||||
            <ion-list *ngIf="!plans.empty" class="ion-no-margin">
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngFor="let plan of plans.items" [attr.aria-label]="plan.name"
 | 
			
		||||
                    (click)="plans.select(plan)" [attr.aria-current]="plans.getItemAriaCurrent(plan)" button>
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
 | 
			
		||||
@ -53,7 +53,7 @@
 | 
			
		||||
:host-context([dir=rtl]) {
 | 
			
		||||
    .addon-messages-conversation-item,
 | 
			
		||||
    .addon-message-discussion {
 | 
			
		||||
        h2  ion-icon {
 | 
			
		||||
        h2 ion-icon {
 | 
			
		||||
            margin-right: 2px;
 | 
			
		||||
            margin-left: 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
            <core-empty-box *ngIf="!hasContacts && searchString != ''" icon="fas-address-book"
 | 
			
		||||
                [message]="'addon.messages.nousersfound' | translate"></core-empty-box>
 | 
			
		||||
 | 
			
		||||
            <ion-list *ngFor="let contactType of contactTypes"  class="ion-no-margin">
 | 
			
		||||
            <ion-list *ngFor="let contactType of contactTypes" class="ion-no-margin">
 | 
			
		||||
                <ng-container *ngIf="contacts[contactType] && (contacts[contactType].length > 0 || contactType === searchType)">
 | 
			
		||||
                    <ion-item-divider>
 | 
			
		||||
                        <ion-label><h2>{{ 'addon.messages.type_' + contactType | translate }}</h2></ion-label>
 | 
			
		||||
@ -39,7 +39,7 @@
 | 
			
		||||
                        <ion-item class="ion-text-wrap addon-messages-conversation-item"
 | 
			
		||||
                            *ngIf="contact.profileimageurl || contact.profileimageurlsmall"
 | 
			
		||||
                            [attr.aria-label]="contact.fullname" (click)="gotoDiscussion(contact.id)" detail="true" button
 | 
			
		||||
                            [attr.aria-current]="contact.id == discussionUserId ? 'page' :  'false'">
 | 
			
		||||
                            [attr.aria-current]="contact.id == discussionUserId ? 'page' : 'false'">
 | 
			
		||||
                            <core-user-avatar [user]="contact" slot="start" [checkOnline]="contact.showonlinestatus"></core-user-avatar>
 | 
			
		||||
                            <ion-label><h2>{{ contact.fullname }}</h2></ion-label>
 | 
			
		||||
                        </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -25,10 +25,10 @@
 | 
			
		||||
                        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
			
		||||
                    </ion-refresher>
 | 
			
		||||
                    <core-loading [hideUntil]="confirmedLoaded" class="core-loading-center">
 | 
			
		||||
                        <ion-list  class="ion-no-margin">
 | 
			
		||||
                        <ion-list class="ion-no-margin">
 | 
			
		||||
                            <ion-item class="ion-text-wrap addon-messages-conversation-item" (click)="selectUser(contact.id)" button
 | 
			
		||||
                                *ngFor="let contact of confirmedContacts" [attr.aria-label]="contact.fullname" detail="true"
 | 
			
		||||
                                [attr.aria-current]="contact.id == selectedUserId ? 'page' :  'false'">
 | 
			
		||||
                                [attr.aria-current]="contact.id == selectedUserId ? 'page' : 'false'">
 | 
			
		||||
                                <core-user-avatar slot="start" [user]="contact"
 | 
			
		||||
                                    [checkOnline]="contact.showonlinestatus" [linkProfile]="false">
 | 
			
		||||
                                </core-user-avatar>
 | 
			
		||||
@ -62,10 +62,10 @@
 | 
			
		||||
                        <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
			
		||||
                    </ion-refresher>
 | 
			
		||||
                    <core-loading [hideUntil]="requestsLoaded" class="core-loading-center">
 | 
			
		||||
                        <ion-list  class="ion-no-margin">
 | 
			
		||||
                        <ion-list class="ion-no-margin">
 | 
			
		||||
                            <ion-item class="ion-text-wrap addon-messages-conversation-item" *ngFor="let request of requests"
 | 
			
		||||
                                [attr.aria-label]="request.fullname" (click)="selectUser(request.id)" button
 | 
			
		||||
                                [attr.aria-current]="request.id == selectedUserId ? 'page' :  'false'" detail="true">
 | 
			
		||||
                                [attr.aria-current]="request.id == selectedUserId ? 'page' : 'false'" detail="true">
 | 
			
		||||
                                <core-user-avatar slot="start" [user]="request" [linkProfile]="false"></core-user-avatar>
 | 
			
		||||
                                <ion-label>
 | 
			
		||||
                                    <core-format-text [text]="request.fullname" contextLevel="system" [contextInstanceId]="0">
 | 
			
		||||
 | 
			
		||||
@ -411,7 +411,7 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
 | 
			
		||||
            // Fetch messages. Invalidate the cache before fetching.
 | 
			
		||||
            if (this.groupMessagingEnabled) {
 | 
			
		||||
                await AddonMessages.invalidateConversationMessages(this.conversationId!);
 | 
			
		||||
                messages =  await this.getConversationMessages(this.pagesLoaded);
 | 
			
		||||
                messages = await this.getConversationMessages(this.pagesLoaded);
 | 
			
		||||
            } else {
 | 
			
		||||
                await AddonMessages.invalidateDiscussionCache(this.userId!);
 | 
			
		||||
                messages = await this.getDiscussionMessages(this.pagesLoaded);
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,7 @@
 | 
			
		||||
                    </ion-item-divider>
 | 
			
		||||
                    <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let result of search.results" button
 | 
			
		||||
                        [attr.aria-label]="result.fullname" (click)="gotoDiscussion(result.userid, result.messageid)"
 | 
			
		||||
                        [attr.aria-current]="result.userid == discussionUserId ? 'page' :  'false'">
 | 
			
		||||
                        [attr.aria-current]="result.userid == discussionUserId ? 'page' : 'false'">
 | 
			
		||||
                        <core-user-avatar [user]="result" slot="start" [checkOnline]="result.showonlinestatus"></core-user-avatar>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                                <h2>{{ result.fullname }}</h2>
 | 
			
		||||
@ -52,7 +52,7 @@
 | 
			
		||||
                <ng-container *ngIf="!search.showResults">
 | 
			
		||||
                    <ion-item class="ion-text-wrap addon-message-discussion" *ngFor="let discussion of discussions" button
 | 
			
		||||
                        [attr.aria-label]="discussion.fullname" (click)="gotoDiscussion(discussion.message!.user)"
 | 
			
		||||
                        [attr.aria-current]="discussion.message!.user == discussionUserId ? 'page' :  'false'">
 | 
			
		||||
                        [attr.aria-current]="discussion.message!.user == discussionUserId ? 'page' : 'false'">
 | 
			
		||||
                        <core-user-avatar [user]="discussion" slot="start" checkOnline="false"></core-user-avatar>
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <h2>{{ discussion.fullname }}</h2>
 | 
			
		||||
 | 
			
		||||
@ -67,7 +67,7 @@ export class AddonMessagesDiscussions35Page implements OnInit, OnDestroy {
 | 
			
		||||
        protected route: ActivatedRoute,
 | 
			
		||||
    ) {
 | 
			
		||||
 | 
			
		||||
        this.search.loading =  Translate.instant('core.searching');
 | 
			
		||||
        this.search.loading = Translate.instant('core.searching');
 | 
			
		||||
        this.loadingMessages = Translate.instant('core.loading');
 | 
			
		||||
        this.siteId = CoreSites.getCurrentSiteId();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
<ion-content>
 | 
			
		||||
    <core-split-view>
 | 
			
		||||
        <core-search-box (onSubmit)="search($event)" (onClear)="clearSearch()" [disabled]="disableSearch" autocorrect="off"
 | 
			
		||||
            [spellcheck]="false" [autoFocus]="true" [lengthCheck]="1"  searchArea="AddonMessagesSearch"></core-search-box>
 | 
			
		||||
            [spellcheck]="false" [autoFocus]="true" [lengthCheck]="1" searchArea="AddonMessagesSearch"></core-search-box>
 | 
			
		||||
 | 
			
		||||
        <core-loading [hideUntil]="!displaySearching" [message]="'core.searching' | translate">
 | 
			
		||||
            <ion-list *ngIf="displayResults">
 | 
			
		||||
@ -43,7 +43,7 @@
 | 
			
		||||
 | 
			
		||||
        <!-- List of results -->
 | 
			
		||||
        <ion-item class="addon-message-discussion ion-text-wrap" *ngFor="let result of item.results" [attr.aria-label]="result.fullname"
 | 
			
		||||
            (click)="openConversation(result)" [attr.aria-current]="result == selectedResult ? 'page' :  'false'" detail="true"
 | 
			
		||||
            (click)="openConversation(result)" [attr.aria-current]="result == selectedResult ? 'page' : 'false'" detail="true"
 | 
			
		||||
            button>
 | 
			
		||||
            <core-user-avatar slot="start" [user]="result" [checkOnline]="true" [linkProfile]="false"></core-user-avatar>
 | 
			
		||||
            <ion-label>
 | 
			
		||||
 | 
			
		||||
@ -83,7 +83,7 @@
 | 
			
		||||
                        <ng-container *ngIf="!groupMessagingEnabled">
 | 
			
		||||
                            <!-- Tablet view -->
 | 
			
		||||
                            <ion-row class="ion-text-wrap ion-hide-md-down ion-align-items-center">
 | 
			
		||||
                                <ion-col  class="ion-margin-horizontal">{{ processor.displayname }}</ion-col>
 | 
			
		||||
                                <ion-col class="ion-margin-horizontal">{{ processor.displayname }}</ion-col>
 | 
			
		||||
                                <ion-col size="2" class="ion-text-center" *ngFor="let state of ['loggedin', 'loggedoff']">
 | 
			
		||||
                                    <!-- If notifications not disabled, show toggle. -->
 | 
			
		||||
                                    <ion-spinner [hidden]="preferences.disableall ||
 | 
			
		||||
 | 
			
		||||
@ -86,7 +86,7 @@ export type AddonMessagesOfflineMessagesDBRecord = {
 | 
			
		||||
    deviceoffline: number; // If message was stored because device was offline.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type  AddonMessagesOfflineConversationMessagesDBRecord = {
 | 
			
		||||
export type AddonMessagesOfflineConversationMessagesDBRecord = {
 | 
			
		||||
    conversationid: number;
 | 
			
		||||
    text: string;
 | 
			
		||||
    timecreated: number;
 | 
			
		||||
 | 
			
		||||
@ -1165,7 +1165,7 @@ export class AddonMessagesProvider {
 | 
			
		||||
            canLoadMore: false,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const preSets: CoreSiteWSPreSets =  {
 | 
			
		||||
        const preSets: CoreSiteWSPreSets = {
 | 
			
		||||
            cacheKey: this.getCacheKeyForDiscussion(userId),
 | 
			
		||||
        };
 | 
			
		||||
        const params: AddonMessagesGetMessagesWSParams = {
 | 
			
		||||
@ -2012,7 +2012,7 @@ export class AddonMessagesProvider {
 | 
			
		||||
     * Returns whether or not we can mark all messages as read.
 | 
			
		||||
     *
 | 
			
		||||
     * @return If related WS is available on current site.
 | 
			
		||||
     * @since  3.2
 | 
			
		||||
     * @since 3.2
 | 
			
		||||
     */
 | 
			
		||||
    isMarkAllMessagesReadEnabled(): boolean {
 | 
			
		||||
        return CoreSites.wsAvailableInCurrentSite('core_message_mark_all_conversation_messages_as_read') ||
 | 
			
		||||
@ -2023,7 +2023,7 @@ export class AddonMessagesProvider {
 | 
			
		||||
     * Returns whether or not we can count unread messages.
 | 
			
		||||
     *
 | 
			
		||||
     * @return True if enabled, false otherwise.
 | 
			
		||||
     * @since  3.2
 | 
			
		||||
     * @since 3.2
 | 
			
		||||
     */
 | 
			
		||||
    isMessageCountEnabled(): boolean {
 | 
			
		||||
        return CoreSites.wsAvailableInCurrentSite('core_message_get_unread_conversations_count');
 | 
			
		||||
@ -2033,7 +2033,7 @@ export class AddonMessagesProvider {
 | 
			
		||||
     * Returns whether or not the message preferences are enabled for the current site.
 | 
			
		||||
     *
 | 
			
		||||
     * @return True if enabled, false otherwise.
 | 
			
		||||
     * @since  3.2
 | 
			
		||||
     * @since 3.2
 | 
			
		||||
     */
 | 
			
		||||
    isMessagePreferencesEnabled(): boolean {
 | 
			
		||||
        return CoreSites.wsAvailableInCurrentSite('core_message_get_user_message_preferences');
 | 
			
		||||
@ -2100,7 +2100,7 @@ export class AddonMessagesProvider {
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns whether or not we can search messages.
 | 
			
		||||
     *
 | 
			
		||||
     * @since  3.2
 | 
			
		||||
     * @since 3.2
 | 
			
		||||
     */
 | 
			
		||||
    isSearchMessagesEnabled(): boolean {
 | 
			
		||||
        return CoreSites.wsAvailableInCurrentSite('core_message_data_for_messagearea_search_messages');
 | 
			
		||||
@ -2167,7 +2167,7 @@ export class AddonMessagesProvider {
 | 
			
		||||
            conversationid: conversationId,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const preSets: CoreSiteWSPreSets =  {
 | 
			
		||||
        const preSets: CoreSiteWSPreSets = {
 | 
			
		||||
            responseExpected: false,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@ -2187,7 +2187,7 @@ export class AddonMessagesProvider {
 | 
			
		||||
            useridfrom: userIdFrom,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const preSets: CoreSiteWSPreSets =  {
 | 
			
		||||
        const preSets: CoreSiteWSPreSets = {
 | 
			
		||||
            typeExpected: 'boolean',
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@ -2834,7 +2834,7 @@ export class AddonMessagesProvider {
 | 
			
		||||
     * @param discussions List of discussions.
 | 
			
		||||
     * @param siteId Site ID. If not defined, current site.
 | 
			
		||||
     */
 | 
			
		||||
    protected storeUsersFromDiscussions(discussions:  { [userId: number]: AddonMessagesDiscussion }, siteId?: string): void {
 | 
			
		||||
    protected storeUsersFromDiscussions(discussions: { [userId: number]: AddonMessagesDiscussion }, siteId?: string): void {
 | 
			
		||||
        const users: CoreUserBasicData[] = [];
 | 
			
		||||
 | 
			
		||||
        for (const userId in discussions) {
 | 
			
		||||
@ -3377,7 +3377,7 @@ export type AddonMessagesMarkMessageReadResult = {
 | 
			
		||||
 * Result of WS core_message_send_instant_messages.
 | 
			
		||||
 */
 | 
			
		||||
export type AddonMessagesSendInstantMessagesMessage = {
 | 
			
		||||
    msgid: number; // Test this to know if it succeeds:  id of the created message if it succeeded, -1 when failed.
 | 
			
		||||
    msgid: number; // Test this to know if it succeeds: i of the created message if it succeeded, -1 when failed.
 | 
			
		||||
    clientmsgid?: string; // Your own id for the message.
 | 
			
		||||
    errormessage?: string; // Error message - if it failed.
 | 
			
		||||
    text?: string; // @since 3.6. The text of the message.
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
 | 
			
		||||
            [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
 | 
			
		||||
@ -601,7 +601,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
 | 
			
		||||
            disabled: false,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this.originalGrades =  {
 | 
			
		||||
        this.originalGrades = {
 | 
			
		||||
            addAttempt: false,
 | 
			
		||||
            applyToAll: false,
 | 
			
		||||
            outcomes: {},
 | 
			
		||||
@ -613,7 +613,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
 | 
			
		||||
            // If we have data about the grader, get its profile.
 | 
			
		||||
            if (feedback.grade && feedback.grade.grader > 0) {
 | 
			
		||||
                try {
 | 
			
		||||
                    this.grader =  await CoreUser.getProfile(feedback.grade.grader, this.courseId);
 | 
			
		||||
                    this.grader = await CoreUser.getProfile(feedback.grade.grader, this.courseId);
 | 
			
		||||
                } catch {
 | 
			
		||||
                    // Ignore errors.
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
            <ion-back-button [text]="'core.back' | translate"></ion-back-button>
 | 
			
		||||
        </ion-buttons>
 | 
			
		||||
        <ion-title>
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId"  [courseId]="courseId">
 | 
			
		||||
            <core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
 | 
			
		||||
            </core-format-text>
 | 
			
		||||
        </ion-title>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,7 @@ export class AddonModAssignSubmissionListPage implements AfterViewInit, OnDestro
 | 
			
		||||
    assign?: AddonModAssignAssign; // Assignment.
 | 
			
		||||
    submissions: AddonModAssignSubmissionListManager; // List of submissions
 | 
			
		||||
    loaded = false; // Whether data has been loaded.
 | 
			
		||||
    haveAllParticipants  = true; // Whether all participants have been loaded.
 | 
			
		||||
    haveAllParticipants = true; // Whether all participants have been loaded.
 | 
			
		||||
    groupId = 0; // Group ID to show.
 | 
			
		||||
    courseId!: number; // Course ID the assignment belongs to.
 | 
			
		||||
    moduleId!: number; // Module ID the submission belongs to.
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ export class AddonModAssignSubmissionReviewPage implements OnInit, CanLeave {
 | 
			
		||||
    title = ''; // Title to display.
 | 
			
		||||
    moduleId!: number; // Module ID the submission belongs to.
 | 
			
		||||
    courseId!: number; // Course ID the assignment belongs to.
 | 
			
		||||
    submitId!: number; //  User that did the submission.
 | 
			
		||||
    submitId!: number; // User that did the submission.
 | 
			
		||||
    blindId?: number; // Blinded user ID (if it's blinded).
 | 
			
		||||
    loaded = false; // Whether data has been loaded.
 | 
			
		||||
    canSaveGrades = false; // Whether the user can save grades.
 | 
			
		||||
 | 
			
		||||
@ -464,7 +464,7 @@ export class AddonModAssignSyncProvider extends CoreCourseActivitySyncBaseProvid
 | 
			
		||||
 | 
			
		||||
        // Override offline grade and outcomes based on the gradebook data.
 | 
			
		||||
        grades.forEach((grade: CoreGradesFormattedItem | CoreGradesFormattedRow) => {
 | 
			
		||||
            if ('gradedategraded' in  grade && (grade.gradedategraded || 0) >= offlineData.timemodified) {
 | 
			
		||||
            if ('gradedategraded' in grade && (grade.gradedategraded || 0) >= offlineData.timemodified) {
 | 
			
		||||
                if (!grade.outcomeid && !grade.scaleid) {
 | 
			
		||||
                    if (gradeInfo && gradeInfo.scale) {
 | 
			
		||||
                        offlineData.grade = this.getSelectedScaleId(gradeInfo.scale, grade.grade || '');
 | 
			
		||||
 | 
			
		||||
@ -90,7 +90,7 @@ export class AddonModAssignProvider {
 | 
			
		||||
    static readonly SUBMITTED_FOR_GRADING_EVENT = 'addon_mod_assign_submitted_for_grading';
 | 
			
		||||
    static readonly GRADED_EVENT = 'addon_mod_assign_graded';
 | 
			
		||||
 | 
			
		||||
    protected gradingOfflineEnabled: {[siteId: string]: boolean}  = {};
 | 
			
		||||
    protected gradingOfflineEnabled: {[siteId: string]: boolean} = {};
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the user can submit in offline. This should only be used if submissionStatus.lastattempt.cansubmit cannot
 | 
			
		||||
@ -1302,7 +1302,7 @@ export class AddonModAssignProvider {
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (error)  {
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (error && !CoreUtils.isWebServiceError(error)) {
 | 
			
		||||
                // Couldn't connect to server, store in offline.
 | 
			
		||||
                return storeOffline();
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,7 @@ export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmiss
 | 
			
		||||
                // No offline data, get the online files.
 | 
			
		||||
                this.files = AddonModAssign.getSubmissionPluginAttachments(this.plugin);
 | 
			
		||||
            }
 | 
			
		||||
        } finally  {
 | 
			
		||||
        } finally {
 | 
			
		||||
            CoreFileSession.setFiles(this.component, this.assign.id, this.files);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
    <nav>
 | 
			
		||||
        <ion-list>
 | 
			
		||||
            <ion-item class="ion-text-wrap" *ngFor="let chapter of chapters" (click)="loadChapter(chapter.id)"
 | 
			
		||||
                [attr.aria-current]="selected == chapter.id ? 'page' :  'false'" button
 | 
			
		||||
                [attr.aria-current]="selected == chapter.id ? 'page' : 'false'" button
 | 
			
		||||
                [class.item-dimmed]="chapter.hidden">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <p [class.ion-padding-left]="addPadding && chapter.level == 1 ? true : null">
 | 
			
		||||
 | 
			
		||||
@ -33,8 +33,8 @@ export class AddonModBookIndexLinkHandlerService extends CoreContentLinksModuleI
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the mod params necessary to open an activity.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  url      The URL to treat.
 | 
			
		||||
     * @param  params   The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
 | 
			
		||||
     * @param url      The URL to treat.
 | 
			
		||||
     * @param params   The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1}
 | 
			
		||||
     * @return List of params to pass to navigateToModule / navigateToModuleByInstance.
 | 
			
		||||
     */
 | 
			
		||||
    getPageParams(url: string, params: Record<string, string>): Params {
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
 | 
			
		||||
            [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
 | 
			
		||||
@ -201,7 +201,7 @@ export class AddonModChatChatPage implements OnInit, OnDestroy {
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the user fullname for a beep.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  id User Id before parsing.
 | 
			
		||||
     * @param id User Id before parsing.
 | 
			
		||||
     * @return User fullname.
 | 
			
		||||
     */
 | 
			
		||||
    protected async getUserFullname(id: string): Promise<string> {
 | 
			
		||||
 | 
			
		||||
@ -120,7 +120,7 @@ export class AddonModChatSessionMessagesPage implements OnInit {
 | 
			
		||||
            return user.fullname;
 | 
			
		||||
        } catch {
 | 
			
		||||
            // Error getting profile.
 | 
			
		||||
            return  id;
 | 
			
		||||
            return id;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -109,7 +109,7 @@ export class AddonModChatHelperProvider {
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the date should be displayed between messages (when the day changes at midnight for example).
 | 
			
		||||
     *
 | 
			
		||||
     * @param message  New message object.
 | 
			
		||||
     * @param message New message object.
 | 
			
		||||
     * @param prevMessage Previous message object.
 | 
			
		||||
     * @return True if messages are from diferent days, false othetwise.
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
 | 
			
		||||
 | 
			
		||||
@ -346,7 +346,7 @@ export class AddonModChoiceProvider {
 | 
			
		||||
    async invalidateOptions(choiceId: number, siteId?: string): Promise<void> {
 | 
			
		||||
        const site = await CoreSites.getSite(siteId);
 | 
			
		||||
 | 
			
		||||
        await  site.invalidateWsCacheForKey(this.getChoiceOptionsCacheKey(choiceId));
 | 
			
		||||
        await site.invalidateWsCacheForKey(this.getChoiceOptionsCacheKey(choiceId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -359,7 +359,7 @@ export class AddonModChoiceProvider {
 | 
			
		||||
    async invalidateResults(choiceId: number, siteId?: string): Promise<void> {
 | 
			
		||||
        const site = await CoreSites.getSite(siteId);
 | 
			
		||||
 | 
			
		||||
        await  site.invalidateWsCacheForKey(this.getChoiceResultsCacheKey(choiceId));
 | 
			
		||||
        await site.invalidateWsCacheForKey(this.getChoiceResultsCacheKey(choiceId));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
    <ion-icon name="fas-search" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
</ion-button>
 | 
			
		||||
 | 
			
		||||
<ion-button *ngIf="action == 'edit'" fill="clear" (click)="editEntry()"  [attr.aria-label]="'core.edit' | translate">
 | 
			
		||||
<ion-button *ngIf="action == 'edit'" fill="clear" (click)="editEntry()" [attr.aria-label]="'core.edit' | translate">
 | 
			
		||||
    <ion-icon name="fas-cog" slot="icon-only" aria-hidden="true"></ion-icon>
 | 
			
		||||
</ion-button>
 | 
			
		||||
 | 
			
		||||
@ -27,8 +27,8 @@
 | 
			
		||||
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 == 'timemodified'">{{ entry.timemodified * 1000 |  coreFormatDate }}</span>
 | 
			
		||||
<span *ngIf="action == 'timeadded'">{{ entry.timecreated * 1000 | coreFormatDate }}</span>
 | 
			
		||||
<span *ngIf="action == 'timemodified'">{{ entry.timemodified * 1000 | coreFormatDate }}</span>
 | 
			
		||||
 | 
			
		||||
<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
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@
 | 
			
		||||
            [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon"
 | 
			
		||||
            [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline"  [priority]="600"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && (hasOffline || hasOfflineRatings) && isOnline" [priority]="600"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
 | 
			
		||||
            [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
 | 
			
		||||
@ -87,7 +87,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
 | 
			
		||||
 | 
			
		||||
    hasNextPage = false;
 | 
			
		||||
    entriesRendered = '';
 | 
			
		||||
    extraImports: Type<unknown>[]  = [AddonModDataComponentsCompileModule];
 | 
			
		||||
    extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
 | 
			
		||||
 | 
			
		||||
    jsData?: {
 | 
			
		||||
        fields: Record<number, AddonModDataField>;
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@
 | 
			
		||||
        <ion-toggle [(ngModel)]="search.searchingAdvanced"></ion-toggle>
 | 
			
		||||
    </ion-item>
 | 
			
		||||
    <form (ngSubmit)="searchEntries($event)" [formGroup]="searchForm" #searchFormEl>
 | 
			
		||||
        <ion-list  class="ion-no-margin">
 | 
			
		||||
        <ion-list class="ion-no-margin">
 | 
			
		||||
            <ion-item [hidden]="search.searchingAdvanced">
 | 
			
		||||
                <ion-label></ion-label>
 | 
			
		||||
                <ion-input type="text" placeholder="{{ 'addon.mod_data.search' | translate}}"
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ export class AddonModDataSearchComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
    advancedSearch = '';
 | 
			
		||||
    advancedIndexed: CoreFormFields = {};
 | 
			
		||||
    extraImports: Type<unknown>[]  = [AddonModDataComponentsCompileModule];
 | 
			
		||||
    extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
 | 
			
		||||
 | 
			
		||||
    searchForm: FormGroup;
 | 
			
		||||
    jsData?: {
 | 
			
		||||
 | 
			
		||||
@ -93,7 +93,7 @@ export class AddonModDataFieldDateHandlerService implements AddonModDataFieldHan
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
                subfield: 'year',
 | 
			
		||||
                value:  date[0],
 | 
			
		||||
                value: date[0],
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                fieldid: field.id,
 | 
			
		||||
 | 
			
		||||
@ -78,14 +78,14 @@ export class AddonModDataFieldFileHandlerService implements AddonModDataFieldHan
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditFiles(field: AddonModDataField): CoreFileEntry[] {
 | 
			
		||||
        return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT,  field.dataid + '_' + field.id);
 | 
			
		||||
        return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    hasFieldDataChanged(field: AddonModDataField, inputData: CoreFormFields, originalFieldData: AddonModDataEntryField): boolean {
 | 
			
		||||
        const files = CoreFileSession.getFiles(AddonModDataProvider.COMPONENT,  field.dataid + '_' + field.id) || [];
 | 
			
		||||
        const files = CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id) || [];
 | 
			
		||||
        let originalFiles = (originalFieldData && originalFieldData.files) || [];
 | 
			
		||||
 | 
			
		||||
        if (originalFiles.length) {
 | 
			
		||||
 | 
			
		||||
@ -146,7 +146,7 @@ export class AddonModDataFieldLatlongComponent extends AddonModDataFieldPluginCo
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CoreDomUtils.showErrorModalDefault(error,  'Error getting location');
 | 
			
		||||
        CoreDomUtils.showErrorModalDefault(error, 'Error getting location');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -133,7 +133,7 @@ export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginCo
 | 
			
		||||
                }
 | 
			
		||||
            }, 1);
 | 
			
		||||
 | 
			
		||||
            this.width  = CoreDomUtils.formatPixelsSize(this.field.param1);
 | 
			
		||||
            this.width = CoreDomUtils.formatPixelsSize(this.field.param1);
 | 
			
		||||
            this.height = CoreDomUtils.formatPixelsSize(this.field.param2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -89,7 +89,7 @@ export class AddonModDataFieldPictureHandlerService implements AddonModDataField
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    getFieldEditFiles(field: AddonModDataField): CoreFileEntry[] {
 | 
			
		||||
        return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT,  field.dataid + '_' + field.id);
 | 
			
		||||
        return CoreFileSession.getFiles(AddonModDataProvider.COMPONENT, field.dataid + '_' + field.id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,7 @@ export class AddonModDataEditPage implements OnInit {
 | 
			
		||||
    groupInfo?: CoreGroupInfo;
 | 
			
		||||
    editFormRender = '';
 | 
			
		||||
    editForm: FormGroup;
 | 
			
		||||
    extraImports: Type<unknown>[]  = [AddonModDataComponentsCompileModule];
 | 
			
		||||
    extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
 | 
			
		||||
    jsData?: {
 | 
			
		||||
        fields: Record<number, AddonModDataField>;
 | 
			
		||||
        database?: AddonModDataData;
 | 
			
		||||
 | 
			
		||||
@ -77,7 +77,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
 | 
			
		||||
    showComments = false;
 | 
			
		||||
    entryHtml = '';
 | 
			
		||||
    siteId: string;
 | 
			
		||||
    extraImports: Type<unknown>[]  = [AddonModDataComponentsCompileModule];
 | 
			
		||||
    extraImports: Type<unknown>[] = [AddonModDataComponentsCompileModule];
 | 
			
		||||
    jsData?: {
 | 
			
		||||
        fields: Record<number, AddonModDataField>;
 | 
			
		||||
        entries: Record<number, AddonModDataEntry>;
 | 
			
		||||
 | 
			
		||||
@ -399,7 +399,7 @@ export class AddonModDataHelperProvider {
 | 
			
		||||
        database: AddonModDataData,
 | 
			
		||||
        accessInfo: AddonModDataGetDataAccessInformationWSResponse,
 | 
			
		||||
        entry: AddonModDataEntry,
 | 
			
		||||
    ):  Record<AddonModDataAction, boolean> {
 | 
			
		||||
    ): Record<AddonModDataAction, boolean> {
 | 
			
		||||
        return {
 | 
			
		||||
            add: false, // Not directly used on entries.
 | 
			
		||||
            more: true,
 | 
			
		||||
@ -719,7 +719,7 @@ export class AddonModDataHelperProvider {
 | 
			
		||||
                // Ignore errors.
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            CoreEvents.trigger(AddonModDataProvider.ENTRY_CHANGED, { dataId, entryId,  deleted: true }, siteId);
 | 
			
		||||
            CoreEvents.trigger(AddonModDataProvider.ENTRY_CHANGED, { dataId, entryId, deleted: true }, siteId);
 | 
			
		||||
 | 
			
		||||
            CoreDomUtils.showToast('addon.mod_data.recorddeleted', true, 3000);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -481,7 +481,7 @@ export type AddonModDataSyncResult = {
 | 
			
		||||
    updated: boolean; // Whether some data was sent to the server or offline data was updated.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export type AddonModDataAutoSyncData =  {
 | 
			
		||||
export type AddonModDataAutoSyncData = {
 | 
			
		||||
    dataId: number;
 | 
			
		||||
    warnings: string[];
 | 
			
		||||
    entryId?: number;
 | 
			
		||||
 | 
			
		||||
@ -635,7 +635,7 @@ export class AddonModDataProvider {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get  access information for a given database.
 | 
			
		||||
     * Get access information for a given database.
 | 
			
		||||
     *
 | 
			
		||||
     * @param dataId Data ID.
 | 
			
		||||
     * @param options Other options.
 | 
			
		||||
@ -1304,7 +1304,7 @@ type AddonModDataDeleteEntryWSParams = {
 | 
			
		||||
 */
 | 
			
		||||
type AddonModDataUpdateEntryWSParams = {
 | 
			
		||||
    entryid: number; // The entry record id.
 | 
			
		||||
    data: AddonModDataEntryWSField[];  // The fields data to be updated.
 | 
			
		||||
    data: AddonModDataEntryWSField[]; // The fields data to be updated.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@
 | 
			
		||||
                        <ion-label>
 | 
			
		||||
                            <h2 *ngIf="item.name" [core-mark-required]="item.required">
 | 
			
		||||
                                <span *ngIf="feedback!.autonumbering && item.itemnumber">{{item.itemnumber}}. </span>
 | 
			
		||||
                                <core-format-text  [component]="component" [componentId]="cmId" [text]="item.name"
 | 
			
		||||
                                <core-format-text [component]="component" [componentId]="cmId" [text]="item.name"
 | 
			
		||||
                                    contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
 | 
			
		||||
                                </core-format-text>
 | 
			
		||||
                            </h2>
 | 
			
		||||
 | 
			
		||||
@ -75,7 +75,7 @@
 | 
			
		||||
                            [required]="item.required" name="{{item.typ}}_{{item.id}}">
 | 
			
		||||
                            <ion-item *ngFor="let option of item.choices">
 | 
			
		||||
                                <ion-label>
 | 
			
		||||
                                    <core-format-text  [component]="component" [componentId]="cmId"
 | 
			
		||||
                                    <core-format-text [component]="component" [componentId]="cmId"
 | 
			
		||||
                                        [text]="option.label" contextLevel="module" [contextInstanceId]="cmId"
 | 
			
		||||
                                        [wsNotFiltered]="true" [courseId]="courseId">
 | 
			
		||||
                                    </core-format-text>
 | 
			
		||||
@ -146,7 +146,7 @@
 | 
			
		||||
                        {{ 'addon.mod_feedback.feedback_submitted_offline' | translate }}
 | 
			
		||||
                    </p>
 | 
			
		||||
                    <p *ngIf="completionPageContents">
 | 
			
		||||
                        <core-format-text  [component]="component" componentId="componentId" [text]="completionPageContents"
 | 
			
		||||
                        <core-format-text [component]="component" componentId="componentId" [text]="completionPageContents"
 | 
			
		||||
                            contextLevel="module" [contextInstanceId]="cmId" [courseId]="courseId">
 | 
			
		||||
                        </core-format-text>
 | 
			
		||||
                    </p>
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
            <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
 | 
			
		||||
        </ion-refresher>
 | 
			
		||||
        <core-loading [hideUntil]="loaded">
 | 
			
		||||
            <ion-list  class="ion-no-margin">
 | 
			
		||||
            <ion-list class="ion-no-margin">
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngIf="groupInfo && (groupInfo.separateGroups || groupInfo.visibleGroups)">
 | 
			
		||||
                    <ion-label id="addon-feedback-groupslabel">
 | 
			
		||||
                        <ng-container *ngIf="groupInfo.separateGroups">{{'core.groupsseparate' | translate }}</ng-container>
 | 
			
		||||
 | 
			
		||||
@ -117,7 +117,7 @@ export class AddonModFeedbackHelperProvider {
 | 
			
		||||
                    if (itemData.typ == 'multichoice' || itemData.typ == 'multichoicerated') {
 | 
			
		||||
                        value = itemData.value || 0;
 | 
			
		||||
                    } else if (this.isNumericItem(itemData)) {
 | 
			
		||||
                        value = itemData.value || itemData.value  == 0 ? itemData.value : '';
 | 
			
		||||
                        value = itemData.value || itemData.value == 0 ? itemData.value : '';
 | 
			
		||||
 | 
			
		||||
                        if (value != '') {
 | 
			
		||||
                            if ((itemData.rangefrom != '' && value < itemData.rangefrom) ||
 | 
			
		||||
@ -126,7 +126,7 @@ export class AddonModFeedbackHelperProvider {
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        value = itemData.value || itemData.value  == 0 ? itemData.value : '';
 | 
			
		||||
                        value = itemData.value || itemData.value == 0 ? itemData.value : '';
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    answered = !!value;
 | 
			
		||||
 | 
			
		||||
@ -511,7 +511,7 @@ export class AddonModFeedbackProvider {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get  access information for a given feedback.
 | 
			
		||||
     * Get access information for a given feedback.
 | 
			
		||||
     *
 | 
			
		||||
     * @param feedbackId Feedback ID.
 | 
			
		||||
     * @param options Other options.
 | 
			
		||||
 | 
			
		||||
@ -255,7 +255,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
 | 
			
		||||
            componentProps: {
 | 
			
		||||
                post: this.post,
 | 
			
		||||
                component: this.component,
 | 
			
		||||
                componentId:  this.componentId,
 | 
			
		||||
                componentId: this.componentId,
 | 
			
		||||
                forum: this.forum,
 | 
			
		||||
            },
 | 
			
		||||
            backdropDismiss: false,
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
    <ion-list id="addon-mod-forum-sort-selector" role="listbox" aria-labelledby="addon-mod-forum-sort-order-label">
 | 
			
		||||
        <ng-container *ngFor="let sortOrder of sortOrders">
 | 
			
		||||
            <ion-item class="ion-text-wrap" detail="false" role="combobox"
 | 
			
		||||
                [attr.aria-current]="selected == sortOrder.value ? 'page' :  'false'" [attr.aria-label]="sortOrder.label | translate"
 | 
			
		||||
                [attr.aria-current]="selected == sortOrder.value ? 'page' : 'false'" [attr.aria-label]="sortOrder.label | translate"
 | 
			
		||||
                (click)="selectSortOrder(sortOrder)" button aria-haspopup="dialog">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <h2>{{ sortOrder.label | translate }}</h2>
 | 
			
		||||
 | 
			
		||||
@ -89,7 +89,7 @@
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
        <div *ngIf="startingPost"  class="ion-margin-bottom">
 | 
			
		||||
        <div *ngIf="startingPost" class="ion-margin-bottom">
 | 
			
		||||
            <addon-mod-forum-post
 | 
			
		||||
                [post]="startingPost" [discussion]="discussion" [courseId]="courseId" [highlight]="true"
 | 
			
		||||
                [discussionId]="discussionId" [component]="component" [componentId]="cmId"
 | 
			
		||||
 | 
			
		||||
@ -531,9 +531,9 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
 | 
			
		||||
    /**
 | 
			
		||||
     * Convenience function to load discussion.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  forumId Forum ID.
 | 
			
		||||
     * @param  cmId Forum cmid.
 | 
			
		||||
     * @param  discussionId Discussion ID.
 | 
			
		||||
     * @param forumId Forum ID.
 | 
			
		||||
     * @param cmId Forum cmid.
 | 
			
		||||
     * @param discussionId Discussion ID.
 | 
			
		||||
     * @return Promise resolved when done.
 | 
			
		||||
     */
 | 
			
		||||
    protected async loadDiscussion(forumId: number, cmId: number, discussionId: number): Promise<void> {
 | 
			
		||||
 | 
			
		||||
@ -465,7 +465,7 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLea
 | 
			
		||||
    async add(): Promise<void> {
 | 
			
		||||
        const forumName = this.forum.name;
 | 
			
		||||
        const subject = this.newDiscussion.subject;
 | 
			
		||||
        let  message = this.newDiscussion.message || '';
 | 
			
		||||
        let message = this.newDiscussion.message || '';
 | 
			
		||||
        const pin = this.newDiscussion.pin;
 | 
			
		||||
        const attachments = this.newDiscussion.files;
 | 
			
		||||
        const discTimecreated = this.timeCreated || Date.now();
 | 
			
		||||
 | 
			
		||||
@ -145,7 +145,7 @@ export class AddonModForumModuleHandlerService implements CoreCourseModuleHandle
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data.extraBadge =  Translate.instant('core.loading');
 | 
			
		||||
        data.extraBadge = Translate.instant('core.loading');
 | 
			
		||||
        data.extraBadgeColor = 'light';
 | 
			
		||||
 | 
			
		||||
        await CoreUtils.ignoreErrors(AddonModForum.invalidateForumData(courseId));
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
    <nav>
 | 
			
		||||
        <ion-list>
 | 
			
		||||
            <ion-item *ngFor="let item of items" (click)="loadItem(item.href)"
 | 
			
		||||
                [attr.aria-current]="selected == item.href ? 'page' :  'false'" button>
 | 
			
		||||
                [attr.aria-current]="selected == item.href ? 'page' : 'false'" button>
 | 
			
		||||
                <ion-label [class.core-bold]="!item.href">
 | 
			
		||||
                    <span class="ion-padding-left" *ngFor="let i of getNumberForPadding(item.level)"></span>{{item.title}}
 | 
			
		||||
                </ion-label>
 | 
			
		||||
 | 
			
		||||
@ -144,7 +144,7 @@ export class AddonModImscpProvider {
 | 
			
		||||
     * @return Cache key.
 | 
			
		||||
     */
 | 
			
		||||
    protected getImscpDataCacheKey(courseId: number): string {
 | 
			
		||||
        return ROOT_CACHE_KEY +  'imscp:' + courseId;
 | 
			
		||||
        return ROOT_CACHE_KEY + 'imscp:' + courseId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
 | 
			
		||||
 | 
			
		||||
@ -195,7 +195,7 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
 | 
			
		||||
                        this.preventReasons = [preventReason!];
 | 
			
		||||
                        lessonReady = false;
 | 
			
		||||
                    }
 | 
			
		||||
                } else  {
 | 
			
		||||
                } else {
 | 
			
		||||
                    // Lesson cannot be started.
 | 
			
		||||
                    this.preventReasons = [preventReason!];
 | 
			
		||||
                    lessonReady = false;
 | 
			
		||||
 | 
			
		||||
@ -884,7 +884,7 @@ export class AddonModLessonProvider {
 | 
			
		||||
                // Answer found.
 | 
			
		||||
                result.correctanswer = this.isAnswerCorrect(lesson, pageData.page!.id, answer, pageIndex);
 | 
			
		||||
                result.newpageid = answer.jumpto || 0;
 | 
			
		||||
                result.response  = answer.response || '';
 | 
			
		||||
                result.response = answer.response || '';
 | 
			
		||||
                result.studentanswer = result.userresponse = answer.answer || '';
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
@ -3195,7 +3195,7 @@ export class AddonModLessonProvider {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let nAttempts: number | undefined;
 | 
			
		||||
        result.attemptsremaining  = 0;
 | 
			
		||||
        result.attemptsremaining = 0;
 | 
			
		||||
        result.maxattemptsreached = false;
 | 
			
		||||
 | 
			
		||||
        if (result.noanswer) {
 | 
			
		||||
@ -3902,7 +3902,7 @@ export type AddonModLessonGetPagesWSResponse = {
 | 
			
		||||
 */
 | 
			
		||||
export type AddonModLessonGetPagesPageWSData = {
 | 
			
		||||
    page: AddonModLessonPageWSData; // Page fields.
 | 
			
		||||
    answerids: number[]; // List of answers ids (empty for content pages in  Moodle 1.9).
 | 
			
		||||
    answerids: number[]; // List of answers ids (empty for content pages in Moodle 1.9).
 | 
			
		||||
    jumps: number[]; // List of possible page jumps.
 | 
			
		||||
    filescount: number; // The total number of files attached to the page.
 | 
			
		||||
    filessizetotal: number; // The total size of the files.
 | 
			
		||||
 | 
			
		||||
@ -119,7 +119,7 @@ export class AddonModLtiModuleHandlerService implements CoreCourseModuleHandler
 | 
			
		||||
        const siteId = CoreSites.getCurrentSiteId();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            await CoreFilepool.downloadUrl(siteId,  icon, false, AddonModLtiProvider.COMPONENT, module.id);
 | 
			
		||||
            await CoreFilepool.downloadUrl(siteId, icon, false, AddonModLtiProvider.COMPONENT, module.id);
 | 
			
		||||
 | 
			
		||||
            // Get the internal URL.
 | 
			
		||||
            const url = await CoreFilepool.getSrcByUrl(siteId, icon, AddonModLtiProvider.COMPONENT, module.id);
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
 | 
			
		||||
 | 
			
		||||
@ -176,7 +176,7 @@ export class AddonModQuizHelperProvider {
 | 
			
		||||
            throw new CoreCanceledError();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return  modalData;
 | 
			
		||||
        return modalData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -2042,7 +2042,7 @@ export type AddonModQuizAttemptWSData = {
 | 
			
		||||
    timefinish?: number; // Time when the attempt was submitted. 0 if the attempt has not been submitted yet.
 | 
			
		||||
    timemodified?: number; // Last modified time.
 | 
			
		||||
    timemodifiedoffline?: number; // Last modified time via webservices.
 | 
			
		||||
    timecheckstate?: number; // Next time quiz cron should check attempt for state changes.  NULL means never check.
 | 
			
		||||
    timecheckstate?: number; // Next time quiz cron should check attempt for state changes. NULL means never check.
 | 
			
		||||
    sumgrades?: number | null; // Total marks for this attempt.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" [iconAction]="syncIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="500" [content]="prefetchText" (action)="prefetch($event)"
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,7 @@
 | 
			
		||||
            <ng-container *ngFor="let sco of toc">
 | 
			
		||||
                <ion-item *ngIf="sco.isvisible" class="ion-text-wrap" [detail]="sco.prereq && sco.launch"
 | 
			
		||||
                    [ngClass]="'core-padding-' + sco.level + ' addon-mod_scorm-type-' + sco.scormtype"
 | 
			
		||||
                    [attr.aria-current]="selected == sco.id ? 'page' :  'false'" (click)="loadSco(sco)"
 | 
			
		||||
                    [attr.aria-current]="selected == sco.id ? 'page' : 'false'" (click)="loadSco(sco)"
 | 
			
		||||
                    [disabled]="!sco.prereq || !sco.launch ? true : null" [button]="sco.prereq && sco.launch">
 | 
			
		||||
                    <ion-icon *ngIf="sco.icon" [name]="sco.icon.icon" [attr.aria-label]="sco.icon.description" slot="start">
 | 
			
		||||
                    </ion-icon>
 | 
			
		||||
 | 
			
		||||
@ -893,7 +893,7 @@ export class AddonModScormProvider {
 | 
			
		||||
 | 
			
		||||
        const data = await this.getScormUserData(scormId, attempt, userDataOptions);
 | 
			
		||||
 | 
			
		||||
        const trackDataBySCO: Record<string, Record<string, AddonModScormDataValue>>  = {};
 | 
			
		||||
        const trackDataBySCO: Record<string, Record<string, AddonModScormDataValue>> = {};
 | 
			
		||||
 | 
			
		||||
        // First populate trackDataBySCO to index by SCO identifier.
 | 
			
		||||
        // We want the full list first because it's needed by evalPrerequisites.
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)"
 | 
			
		||||
            [iconAction]="syncIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@
 | 
			
		||||
                    <ion-label><h2>{{ letter.label }}</h2></ion-label>
 | 
			
		||||
                </ion-item-divider>
 | 
			
		||||
                <ion-item class="ion-text-wrap" *ngFor="let page of letter.pages" (click)="goToPage(page)"
 | 
			
		||||
                    [attr.aria-current]="selectedTitle == page.title ? 'page' :  'false'" button>
 | 
			
		||||
                    [attr.aria-current]="selectedTitle == page.title ? 'page' : 'false'" button>
 | 
			
		||||
                    <ion-icon name="fas-home" slot="start" *ngIf="page.firstpage" aria-hidden="true"></ion-icon>
 | 
			
		||||
                    <ion-label>
 | 
			
		||||
                        <core-format-text [text]="page.title" contextLevel="module" [contextInstanceId]="moduleId"
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@
 | 
			
		||||
        <ion-item class="ion-text-wrap" *ngFor="let subwiki of group.subwikis" (click)="openSubwiki(subwiki)"
 | 
			
		||||
            [attr.disabled]="!subwiki.canedit && subwiki.id <= 0"
 | 
			
		||||
            [button]="subwiki.canedit || subwiki.id > 0"
 | 
			
		||||
            [attr.aria-current]="isSubwikiSelected(subwiki) ? 'page' :  'false'" detail="false">
 | 
			
		||||
            [attr.aria-current]="isSubwikiSelected(subwiki) ? 'page' : 'false'" detail="false">
 | 
			
		||||
            <ion-label>{{ subwiki.name }}</ion-label>
 | 
			
		||||
            <ion-icon *ngIf="isSubwikiSelected(subwiki)" name="fas-check" slot="end" aria-hidden="true"></ion-icon>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -115,7 +115,7 @@ export class AddonModWorkshopAssessmentStrategyAccumulativeHandlerService implem
 | 
			
		||||
        currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
 | 
			
		||||
        form: AddonModWorkshopGetAssessmentFormDefinitionData,
 | 
			
		||||
    ): Promise<CoreFormFields> {
 | 
			
		||||
        const data: CoreFormFields =  {};
 | 
			
		||||
        const data: CoreFormFields = {};
 | 
			
		||||
        const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
 | 
			
		||||
        let hasErrors = false;
 | 
			
		||||
 | 
			
		||||
@ -135,7 +135,7 @@ export class AddonModWorkshopAssessmentStrategyAccumulativeHandlerService implem
 | 
			
		||||
 | 
			
		||||
                data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
 | 
			
		||||
                data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
 | 
			
		||||
                data['weight__idx_' + idx] = parseInt(field.weight, 10) ||  0;
 | 
			
		||||
                data['weight__idx_' + idx] = parseInt(field.weight, 10) || 0;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -94,7 +94,7 @@ export class AddonModWorkshopAssessmentStrategyCommentsHandlerService implements
 | 
			
		||||
        currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
 | 
			
		||||
        form: AddonModWorkshopGetAssessmentFormDefinitionData,
 | 
			
		||||
    ): Promise<CoreFormFields> {
 | 
			
		||||
        const data: CoreFormFields =  {};
 | 
			
		||||
        const data: CoreFormFields = {};
 | 
			
		||||
        const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
 | 
			
		||||
        let hasErrors = false;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -66,7 +66,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
 | 
			
		||||
            originalValues[n] = {};
 | 
			
		||||
            originalValues[n].peercomment = form.current[n].peercomment || '';
 | 
			
		||||
            originalValues[n].number = field.number; // eslint-disable-line id-blacklist
 | 
			
		||||
            originalValues[n].grade  = form.current[n].grade || '';
 | 
			
		||||
            originalValues[n].grade = form.current[n].grade || '';
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return originalValues;
 | 
			
		||||
@ -98,7 +98,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
 | 
			
		||||
        currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
 | 
			
		||||
        form: AddonModWorkshopGetAssessmentFormDefinitionData,
 | 
			
		||||
    ): Promise<CoreFormFields> {
 | 
			
		||||
        const data: CoreFormFields =  {};
 | 
			
		||||
        const data: CoreFormFields = {};
 | 
			
		||||
        const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
 | 
			
		||||
        let hasErrors = false;
 | 
			
		||||
 | 
			
		||||
@ -118,7 +118,7 @@ export class AddonModWorkshopAssessmentStrategyNumErrorsHandlerService implement
 | 
			
		||||
 | 
			
		||||
                data['gradeid__idx_' + idx] = parseInt(form.current[idx].gradeid, 10) || 0;
 | 
			
		||||
                data['dimensionid__idx_' + idx] = parseInt(field.dimensionid, 10);
 | 
			
		||||
                data['weight__idx_' + idx] = parseInt(field.weight, 10) ||  0;
 | 
			
		||||
                data['weight__idx_' + idx] = parseInt(field.weight, 10) || 0;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -94,7 +94,7 @@ export class AddonModWorkshopAssessmentStrategyRubricHandlerService implements A
 | 
			
		||||
        currentValues: AddonModWorkshopGetAssessmentFormFieldsParsedData[],
 | 
			
		||||
        form: AddonModWorkshopGetAssessmentFormDefinitionData,
 | 
			
		||||
    ): Promise<CoreFormFields> {
 | 
			
		||||
        const data: CoreFormFields =  {};
 | 
			
		||||
        const data: CoreFormFields = {};
 | 
			
		||||
        const errors: AddonModWorkshopAssessmentStrategyFieldErrors = {};
 | 
			
		||||
        let hasErrors = false;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && !hasOffline && isOnline" [priority]="700" [content]="'core.refresh' | translate"
 | 
			
		||||
            (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline"  [priority]="600"
 | 
			
		||||
        <core-context-menu-item *ngIf="loaded && hasOffline && isOnline" [priority]="600"
 | 
			
		||||
            [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon"
 | 
			
		||||
            [closeOnClick]="false">
 | 
			
		||||
        </core-context-menu-item>
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@
 | 
			
		||||
<ion-content>
 | 
			
		||||
    <ion-list>
 | 
			
		||||
        <ng-container *ngFor="let phase of phases">
 | 
			
		||||
            <ion-item-divider [attr.aria-current]="workshopPhase == phase.code ? 'page' :  'false'">
 | 
			
		||||
            <ion-item-divider [attr.aria-current]="workshopPhase == phase.code ? 'page' : 'false'">
 | 
			
		||||
                <ion-label>
 | 
			
		||||
                    <h2>{{ phase.title }}</h2>
 | 
			
		||||
                    <p class="ion-text-wrap" *ngIf="workshopPhase == phase.code">
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@
 | 
			
		||||
                    </span>
 | 
			
		||||
                </ion-label>
 | 
			
		||||
                <core-rich-text-editor [control]="editForm.controls['content']" name="content"
 | 
			
		||||
                    [placeholder]="'addon.mod_workshop.submissioncontent' | translate"  name="content" [component]="component"
 | 
			
		||||
                    [placeholder]="'addon.mod_workshop.submissioncontent' | translate" name="content" [component]="component"
 | 
			
		||||
                    [componentId]="componentId" [autoSave]="true" contextLevel="module" [contextInstanceId]="module.id"
 | 
			
		||||
                    elementId="content_editor" [draftExtraParams]="editorExtraParams"></core-rich-text-editor>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
 | 
			
		||||
@ -61,7 +61,7 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy, Ca
 | 
			
		||||
    component = AddonModWorkshopProvider.COMPONENT;
 | 
			
		||||
    componentId!: number;
 | 
			
		||||
    editForm: FormGroup; // The form group.
 | 
			
		||||
    editorExtraParams:  Record<string, unknown> = {}; // Extra params to identify the draft.
 | 
			
		||||
    editorExtraParams: Record<string, unknown> = {}; // Extra params to identify the draft.
 | 
			
		||||
    workshop?: AddonModWorkshopData;
 | 
			
		||||
    textAvailable = false;
 | 
			
		||||
    textRequired = false;
 | 
			
		||||
 | 
			
		||||
@ -362,7 +362,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy, CanLea
 | 
			
		||||
    /**
 | 
			
		||||
     * Parse assessment to be shown.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  assessment Original assessment.
 | 
			
		||||
     * @param assessment Original assessment.
 | 
			
		||||
     * @return Parsed assessment.
 | 
			
		||||
     */
 | 
			
		||||
    protected parseAssessment(
 | 
			
		||||
 | 
			
		||||
@ -483,7 +483,7 @@ export class AddonModWorkshopHelperProvider {
 | 
			
		||||
        actions.forEach((action) => {
 | 
			
		||||
            switch (action.action) {
 | 
			
		||||
                case AddonModWorkshopAction.ADD:
 | 
			
		||||
                case  AddonModWorkshopAction.UPDATE:
 | 
			
		||||
                case AddonModWorkshopAction.UPDATE:
 | 
			
		||||
                    submission!.title = action.title;
 | 
			
		||||
                    submission!.content = action.content;
 | 
			
		||||
                    submission!.title = action.title;
 | 
			
		||||
@ -492,7 +492,7 @@ export class AddonModWorkshopHelperProvider {
 | 
			
		||||
                    submission!.offline = true;
 | 
			
		||||
                    attachmentsId = action.attachmentsid as CoreFileUploaderStoreFilesResult;
 | 
			
		||||
                    break;
 | 
			
		||||
                case  AddonModWorkshopAction.DELETE:
 | 
			
		||||
                case AddonModWorkshopAction.DELETE:
 | 
			
		||||
                    submission!.deleted = true;
 | 
			
		||||
                    submission!.submissionmodified = action.timemodified / 1000;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
@ -125,7 +125,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
 | 
			
		||||
        } finally {
 | 
			
		||||
            let canDelete = this.notes && this.notes.length > 0;
 | 
			
		||||
            if (canDelete && this.type == 'personal') {
 | 
			
		||||
                canDelete = !!this.notes.find((note) =>  note.usermodified == this.currentUserId);
 | 
			
		||||
                canDelete = !!this.notes.find((note) => note.usermodified == this.currentUserId);
 | 
			
		||||
            }
 | 
			
		||||
            this.canDeleteNotes = canDelete;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -452,7 +452,7 @@ export class AddonQtypeDdMarkerQuestion {
 | 
			
		||||
    /**
 | 
			
		||||
     * Make proportional position of the point.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  point Point coordinates.
 | 
			
		||||
     * @param point Point coordinates.
 | 
			
		||||
     * @return Converted point.
 | 
			
		||||
     */
 | 
			
		||||
    makePointProportional(point: AddonQtypeDdMarkerQuestionPoint): AddonQtypeDdMarkerQuestionPoint {
 | 
			
		||||
 | 
			
		||||
@ -140,7 +140,7 @@
 | 
			
		||||
        div.draghomes img.target {
 | 
			
		||||
            position: absolute;
 | 
			
		||||
            left: -7px; /* This must be half the size of the target image, minus 0.5. */
 | 
			
		||||
            top: -7px;  /* In other words, this works for a 15x15 cross-hair. */
 | 
			
		||||
            top: -7px; /* In other words, this works for a 15x15 cross-hair. */
 | 
			
		||||
        }
 | 
			
		||||
        div.dragitems div.draghome img.target,
 | 
			
		||||
        div.draghomes div.marker img.target {
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@
 | 
			
		||||
    <!-- Checkbox for multiple choice. -->
 | 
			
		||||
    <ng-container *ngIf="multiQuestion.multi">
 | 
			
		||||
        <ion-item class="ion-text-wrap" *ngFor="let option of multiQuestion.options">
 | 
			
		||||
            <ion-label [color]='(option.isCorrect === 1 ? "success": "") +  (option.isCorrect === 0 ? "danger": "")'>
 | 
			
		||||
            <ion-label [color]='(option.isCorrect === 1 ? "success": "") + (option.isCorrect === 0 ? "danger": "")'>
 | 
			
		||||
                <core-format-text [component]="component" [componentId]="componentId" [text]="option.text"
 | 
			
		||||
                    [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId">
 | 
			
		||||
                </core-format-text>
 | 
			
		||||
 | 
			
		||||
@ -132,7 +132,7 @@ export class AddonStorageManagerCourseStoragePage implements OnInit {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const modules: AddonStorageManagerModule[]  = [];
 | 
			
		||||
        const modules: AddonStorageManagerModule[] = [];
 | 
			
		||||
        section.modules.forEach((module) => {
 | 
			
		||||
            if (module.totalSize && module.totalSize > 0) {
 | 
			
		||||
                modules.push(module);
 | 
			
		||||
 | 
			
		||||
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