commit
413c661eda
|
@ -20,10 +20,6 @@
|
||||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<core-loading [hideUntil]="submissions.loaded">
|
<core-loading [hideUntil]="submissions.loaded">
|
||||||
<core-empty-box *ngIf="!submissions || submissions.empty" icon="fas-file-signature"
|
|
||||||
[message]="'addon.mod_assign.submissionstatus_' | translate">
|
|
||||||
</core-empty-box>
|
|
||||||
|
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item class="ion-text-wrap core-group-selector" *ngIf="(groupInfo.separateGroups || groupInfo.visibleGroups)">
|
<ion-item class="ion-text-wrap core-group-selector" *ngIf="(groupInfo.separateGroups || groupInfo.visibleGroups)">
|
||||||
<ion-label id="addon-assign-groupslabel-list">
|
<ion-label id="addon-assign-groupslabel-list">
|
||||||
|
@ -77,6 +73,10 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
|
||||||
|
<core-empty-box *ngIf="!submissions || submissions.empty" icon="fas-file-signature"
|
||||||
|
[message]="'addon.mod_assign.submissionstatus_' | translate">
|
||||||
|
</core-empty-box>
|
||||||
</core-loading>
|
</core-loading>
|
||||||
</core-split-view>
|
</core-split-view>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|
|
@ -205,7 +205,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
|
||||||
downloadable = await AddonModResourceHelper.isMainFileDownloadable(this.module);
|
downloadable = await AddonModResourceHelper.isMainFileDownloadable(this.module);
|
||||||
|
|
||||||
if (downloadable) {
|
if (downloadable) {
|
||||||
if (this.currentStatus === CoreConstants.OUTDATED && !this.isOnline) {
|
if (this.currentStatus === CoreConstants.OUTDATED && !this.isOnline && !this.isExternalFile) {
|
||||||
// Warn the user that the file isn't updated.
|
// Warn the user that the file isn't updated.
|
||||||
const alert = await CoreDomUtils.showAlert(
|
const alert = await CoreDomUtils.showAlert(
|
||||||
undefined,
|
undefined,
|
||||||
|
|
|
@ -175,7 +175,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
this.lastInAppUrl = '';
|
this.lastInAppUrl = '';
|
||||||
|
|
||||||
if (CoreLoginHelper.isWaitingForBrowser()) {
|
if (CoreLoginHelper.isWaitingForBrowser()) {
|
||||||
CoreLoginHelper.setWaitingForBrowser(false);
|
CoreLoginHelper.stopWaitingForBrowser();
|
||||||
CoreLoginHelper.checkLogout();
|
CoreLoginHelper.checkLogout();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -184,7 +184,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||||
// Wait a second before setting it to false since in iOS there could be some frozen WS calls.
|
// Wait a second before setting it to false since in iOS there could be some frozen WS calls.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (CoreLoginHelper.isWaitingForBrowser()) {
|
if (CoreLoginHelper.isWaitingForBrowser()) {
|
||||||
CoreLoginHelper.setWaitingForBrowser(false);
|
CoreLoginHelper.stopWaitingForBrowser();
|
||||||
CoreLoginHelper.checkLogout();
|
CoreLoginHelper.checkLogout();
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
|
@ -103,6 +103,11 @@ export class CoreDelegate<HandlerType extends CoreDelegateHandler> {
|
||||||
this.updateHandlers();
|
this.updateHandlers();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
CoreEvents.on(CoreEvents.COMPLETE_REQUIRED_PROFILE_DATA_FINISHED, (data) => {
|
||||||
|
if (data.siteId === CoreSites.getCurrentSiteId()) {
|
||||||
|
this.updateHandlers();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ import { asyncInstance, AsyncInstance } from '../utils/async-instance';
|
||||||
import { CoreDatabaseTable } from './database/database-table';
|
import { CoreDatabaseTable } from './database/database-table';
|
||||||
import { CoreDatabaseCachingStrategy } from './database/database-table-proxy';
|
import { CoreDatabaseCachingStrategy } from './database/database-table-proxy';
|
||||||
import { CoreSilentError } from './errors/silenterror';
|
import { CoreSilentError } from './errors/silenterror';
|
||||||
import { CoreWindow } from '@singletons/window';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QR Code type enumeration.
|
* QR Code type enumeration.
|
||||||
|
@ -1608,16 +1607,7 @@ export class CoreSite {
|
||||||
if (inApp) {
|
if (inApp) {
|
||||||
return CoreUtils.openInApp(autoLoginUrl, options);
|
return CoreUtils.openInApp(autoLoginUrl, options);
|
||||||
} else {
|
} else {
|
||||||
if ((options.showBrowserWarning || options.showBrowserWarning === undefined) && autoLoginUrl !== url) {
|
options.browserWarningUrl = url;
|
||||||
// Don't display the autologin URL in the warning.
|
|
||||||
try {
|
|
||||||
await CoreWindow.confirmOpenBrowserIfNeeded(url);
|
|
||||||
|
|
||||||
options.showBrowserWarning = false;
|
|
||||||
} catch (error) {
|
|
||||||
return; // Cancelled, stop.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CoreUtils.openInBrowser(autoLoginUrl, options);
|
return CoreUtils.openInBrowser(autoLoginUrl, options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,13 @@
|
||||||
</ion-input>
|
</ion-input>
|
||||||
|
|
||||||
<div class="buttons" slot="end">
|
<div class="buttons" slot="end">
|
||||||
<ion-button fill="clear" *ngIf="isIOS" (click)="openFile($event, true)" [attr.aria-label]="openButtonLabel | translate">
|
<ion-button fill="clear" *ngIf="isIOS && !editMode" (click)="openFile($event, true)"
|
||||||
|
[attr.aria-label]="openButtonLabel | translate">
|
||||||
<ion-icon slot="icon-only" [name]="openButtonIcon" aria-hidden="true"></ion-icon>
|
<ion-icon slot="icon-only" [name]="openButtonIcon" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
|
||||||
<ng-container *ngIf="manage">
|
<ng-container *ngIf="manage">
|
||||||
<ion-button *ngIf="editMode" fill="clear" [attr.aria-label]="'core.save' | translate" color="success" type="submit"
|
<ion-button *ngIf="editMode" fill="clear" [attr.aria-label]="'core.save' | translate" color="success" type="submit">
|
||||||
(click)="changeName(newFileName, $event)">
|
|
||||||
<ion-icon name="fas-check" slot="icon-only" aria-hidden="true"></ion-icon>
|
<ion-icon name="fas-check" slot="icon-only" aria-hidden="true"></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ import { CoreCanceledError } from '@classes/errors/cancelederror';
|
||||||
import { CoreCustomURLSchemes } from '@services/urlschemes';
|
import { CoreCustomURLSchemes } from '@services/urlschemes';
|
||||||
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
|
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
|
||||||
import { CoreText } from '@singletons/text';
|
import { CoreText } from '@singletons/text';
|
||||||
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper provider that provides some common features regarding authentication.
|
* Helper provider that provides some common features regarding authentication.
|
||||||
|
@ -56,7 +57,7 @@ export class CoreLoginHelperProvider {
|
||||||
protected logger: CoreLogger;
|
protected logger: CoreLogger;
|
||||||
protected sessionExpiredCheckingSite: Record<string, boolean> = {};
|
protected sessionExpiredCheckingSite: Record<string, boolean> = {};
|
||||||
protected isOpenEditAlertShown = false;
|
protected isOpenEditAlertShown = false;
|
||||||
protected waitingForBrowser = false;
|
protected waitingForBrowser?: CorePromisedValue<void>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.logger = CoreLogger.getInstance('CoreLoginHelper');
|
this.logger = CoreLogger.getInstance('CoreLoginHelper');
|
||||||
|
@ -768,11 +769,15 @@ export class CoreLoginHelperProvider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await currentSite.openInAppWithAutoLogin(siteUrl + path, undefined, alertMessage);
|
await currentSite.openInAppWithAutoLogin(siteUrl + path, undefined, alertMessage);
|
||||||
|
|
||||||
this.waitingForBrowser = true;
|
|
||||||
} finally {
|
} finally {
|
||||||
this.isOpenEditAlertShown = false;
|
this.isOpenEditAlertShown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.waitForBrowser();
|
||||||
|
|
||||||
|
CoreEvents.trigger(CoreEvents.COMPLETE_REQUIRED_PROFILE_DATA_FINISHED, {
|
||||||
|
path,
|
||||||
|
}, siteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,7 +922,7 @@ export class CoreLoginHelperProvider {
|
||||||
(currentSite.isLoggedOut() ? 'loggedoutssodescription' : 'reconnectssodescription')));
|
(currentSite.isLoggedOut() ? 'loggedoutssodescription' : 'reconnectssodescription')));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.waitingForBrowser = true;
|
this.waitForBrowser();
|
||||||
|
|
||||||
this.openBrowserForSSOLogin(
|
this.openBrowserForSSOLogin(
|
||||||
result.siteUrl,
|
result.siteUrl,
|
||||||
|
@ -950,7 +955,7 @@ export class CoreLoginHelperProvider {
|
||||||
try {
|
try {
|
||||||
await CoreDomUtils.showConfirm(confirmMessage);
|
await CoreDomUtils.showConfirm(confirmMessage);
|
||||||
|
|
||||||
this.waitingForBrowser = true;
|
this.waitForBrowser();
|
||||||
CoreSites.unsetCurrentSite(); // Unset current site to make authentication work fine.
|
CoreSites.unsetCurrentSite(); // Unset current site to make authentication work fine.
|
||||||
|
|
||||||
this.openBrowserForOAuthLogin(
|
this.openBrowserForOAuthLogin(
|
||||||
|
@ -1223,16 +1228,28 @@ export class CoreLoginHelperProvider {
|
||||||
* @return Whether the app is waiting for browser.
|
* @return Whether the app is waiting for browser.
|
||||||
*/
|
*/
|
||||||
isWaitingForBrowser(): boolean {
|
isWaitingForBrowser(): boolean {
|
||||||
return this.waitingForBrowser;
|
return !!this.waitingForBrowser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether the app is waiting for browser.
|
* Start waiting when opening a browser/IAB.
|
||||||
*
|
*
|
||||||
* @param value New value.
|
* @return Promise resolved when the app is resumed.
|
||||||
*/
|
*/
|
||||||
setWaitingForBrowser(value: boolean): void {
|
async waitForBrowser(): Promise<void> {
|
||||||
this.waitingForBrowser = value;
|
if (!this.waitingForBrowser) {
|
||||||
|
this.waitingForBrowser = new CorePromisedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.waitingForBrowser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop waiting for browser.
|
||||||
|
*/
|
||||||
|
stopWaitingForBrowser(): void {
|
||||||
|
this.waitingForBrowser?.resolve();
|
||||||
|
this.waitingForBrowser = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1112,7 +1112,7 @@ export class CoreUtilsProvider {
|
||||||
async openInBrowser(url: string, options: CoreUtilsOpenInBrowserOptions = {}): Promise<void> {
|
async openInBrowser(url: string, options: CoreUtilsOpenInBrowserOptions = {}): Promise<void> {
|
||||||
if (options.showBrowserWarning || options.showBrowserWarning === undefined) {
|
if (options.showBrowserWarning || options.showBrowserWarning === undefined) {
|
||||||
try {
|
try {
|
||||||
await CoreWindow.confirmOpenBrowserIfNeeded(url);
|
await CoreWindow.confirmOpenBrowserIfNeeded(options.browserWarningUrl ?? url);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return; // Cancelled, stop.
|
return; // Cancelled, stop.
|
||||||
}
|
}
|
||||||
|
@ -1836,6 +1836,7 @@ export type CoreUtilsOpenFileOptions = {
|
||||||
*/
|
*/
|
||||||
export type CoreUtilsOpenInBrowserOptions = {
|
export type CoreUtilsOpenInBrowserOptions = {
|
||||||
showBrowserWarning?: boolean; // Whether to display a warning before opening in browser. Defaults to true.
|
showBrowserWarning?: boolean; // Whether to display a warning before opening in browser. Defaults to true.
|
||||||
|
browserWarningUrl?: string; // The URL to display in the warning message. Use it to hide sensitive information.
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -61,6 +61,7 @@ export interface CoreEventsData {
|
||||||
[CoreEvents.APP_LAUNCHED_URL]: CoreEventAppLaunchedData;
|
[CoreEvents.APP_LAUNCHED_URL]: CoreEventAppLaunchedData;
|
||||||
[CoreEvents.ORIENTATION_CHANGE]: CoreEventOrientationData;
|
[CoreEvents.ORIENTATION_CHANGE]: CoreEventOrientationData;
|
||||||
[CoreEvents.COURSE_MODULE_VIEWED]: CoreEventCourseModuleViewed;
|
[CoreEvents.COURSE_MODULE_VIEWED]: CoreEventCourseModuleViewed;
|
||||||
|
[CoreEvents.COMPLETE_REQUIRED_PROFILE_DATA_FINISHED]: CoreEventCompleteRequiredProfileDataFinished;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -115,6 +116,7 @@ export class CoreEvents {
|
||||||
static readonly ACTIVITY_DATA_SENT = 'activity_data_sent';
|
static readonly ACTIVITY_DATA_SENT = 'activity_data_sent';
|
||||||
static readonly DEVICE_REGISTERED_IN_MOODLE = 'device_registered_in_moodle';
|
static readonly DEVICE_REGISTERED_IN_MOODLE = 'device_registered_in_moodle';
|
||||||
static readonly COURSE_MODULE_VIEWED = 'course_module_viewed';
|
static readonly COURSE_MODULE_VIEWED = 'course_module_viewed';
|
||||||
|
static readonly COMPLETE_REQUIRED_PROFILE_DATA_FINISHED = 'complete_required_profile_data_finished';
|
||||||
|
|
||||||
protected static logger = CoreLogger.getInstance('CoreEvents');
|
protected static logger = CoreLogger.getInstance('CoreEvents');
|
||||||
protected static observables: { [eventName: string]: Subject<unknown> } = {};
|
protected static observables: { [eventName: string]: Subject<unknown> } = {};
|
||||||
|
@ -467,3 +469,10 @@ export type CoreEventCourseModuleViewed = {
|
||||||
timeaccess: number;
|
timeaccess: number;
|
||||||
sectionId?: number;
|
sectionId?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data passed to COMPLETE_REQUIRED_PROFILE_DATA_FINISHED event.
|
||||||
|
*/
|
||||||
|
export type CoreEventCompleteRequiredProfileDataFinished = {
|
||||||
|
path: string;
|
||||||
|
};
|
||||||
|
|
|
@ -61,6 +61,11 @@ export class CoreWindow {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove common sensitive information from the URL.
|
||||||
|
url = url
|
||||||
|
.replace(/token=[^&#]+/gi, 'token=secret')
|
||||||
|
.replace(/tokenpluginfile\.php\/[^/]+/gi, 'tokenpluginfile.php/secret');
|
||||||
|
|
||||||
const dontShowAgain = await CoreDomUtils.showPrompt(
|
const dontShowAgain = await CoreDomUtils.showPrompt(
|
||||||
Translate.instant('core.warnopeninbrowser', { url }),
|
Translate.instant('core.warnopeninbrowser', { url }),
|
||||||
undefined,
|
undefined,
|
||||||
|
|
|
@ -25,7 +25,7 @@ information provided here is intended especially for developers.
|
||||||
- The variable "loaded" in CoreCourseModuleMainResourceComponent has been changed to "showLoading" to reflect its purpose better.
|
- The variable "loaded" in CoreCourseModuleMainResourceComponent has been changed to "showLoading" to reflect its purpose better.
|
||||||
- The function getCurrentSection of course formats can now return a forceSelected boolean along with the section (defaults to false if not returned).
|
- The function getCurrentSection of course formats can now return a forceSelected boolean along with the section (defaults to false if not returned).
|
||||||
- The link handlers functions (CoreContentLinksHandler) will now always receive a relative URL instead of an absolute URL. The CoreContentLinksHandlerBase class now adds "^" to the start of the pattern by default to prevent false positives.
|
- The link handlers functions (CoreContentLinksHandler) will now always receive a relative URL instead of an absolute URL. The CoreContentLinksHandlerBase class now adds "^" to the start of the pattern by default to prevent false positives.
|
||||||
|
- The function CoreLoginHelper.setWaitingForBrowser has been removed, use CoreLoginHelper.waitForBrowser and CoreLoginHelper.stopWaitingForBrowser instead.
|
||||||
|
|
||||||
|
|
||||||
=== 3.9.5 ===
|
=== 3.9.5 ===
|
||||||
|
|
Loading…
Reference in New Issue