diff --git a/src/addon/messages/pages/discussion/discussion.html b/src/addon/messages/pages/discussion/discussion.html
index a3b2cee6f..8363436b7 100644
--- a/src/addon/messages/pages/discussion/discussion.html
+++ b/src/addon/messages/pages/discussion/discussion.html
@@ -17,8 +17,8 @@
-
-
+
+
diff --git a/src/addon/messages/pages/discussion/discussion.ts b/src/addon/messages/pages/discussion/discussion.ts
index 853494ce1..1b0036998 100644
--- a/src/addon/messages/pages/discussion/discussion.ts
+++ b/src/addon/messages/pages/discussion/discussion.ts
@@ -1253,8 +1253,6 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
action: 'delete'
}, this.siteId);
- this.conversationId = undefined;
- this.conversation = undefined;
this.messages = [];
}).finally(() => {
this.deleteIcon = 'trash';
diff --git a/src/app/app.scss b/src/app/app.scss
index 5d129a009..1c9b9a924 100644
--- a/src/app/app.scss
+++ b/src/app/app.scss
@@ -1010,7 +1010,7 @@ body.keyboard-is-open {
}
}
- core-ion-tabs .tabbar {
+ core-ion-tabs[tabsplacement="bottom"] .tabbar {
display: none;
}
}
diff --git a/src/config.json b/src/config.json
index 57216340b..7ad4f4a2b 100644
--- a/src/config.json
+++ b/src/config.json
@@ -75,8 +75,8 @@
"notificoncolor": "#f98012",
"statusbarbg": false,
"statusbarlighttext": false,
- "statusbarbgios": false,
- "statusbarlighttextios": false,
+ "statusbarbgios": "#f98012",
+ "statusbarlighttextios": true,
"statusbarbgandroid": "#df7310",
"statusbarlighttextandroid": true,
"statusbarbgremotetheme": "#000000",
diff --git a/src/core/contentlinks/pages/choose-site/choose-site.html b/src/core/contentlinks/pages/choose-site/choose-site.html
index 9124e5e7c..c6a401175 100644
--- a/src/core/contentlinks/pages/choose-site/choose-site.html
+++ b/src/core/contentlinks/pages/choose-site/choose-site.html
@@ -10,10 +10,12 @@
{{ 'core.contentlinks.chooseaccounttoopenlink' | translate }}
{{ url }}
-
-
+
+
+
+
{{site.fullName}}
-
+
{{site.siteUrl}}
diff --git a/src/core/course/providers/default-format.ts b/src/core/course/providers/default-format.ts
index b445158a9..e03341376 100644
--- a/src/core/course/providers/default-format.ts
+++ b/src/core/course/providers/default-format.ts
@@ -167,7 +167,10 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler {
Object.assign(params, { course: course });
if (navCtrl) {
- return navCtrl.push('CoreCourseSectionPage', params);
+ // Don't return the .push promise, we don't want to display a loading modal during the page transition.
+ navCtrl.push('CoreCourseSectionPage', params);
+
+ return Promise.resolve();
} else {
// Open the course in the "phantom" tab.
this.loginHelper = this.loginHelper || this.injector.get(CoreLoginHelperProvider);
diff --git a/src/providers/urlschemes.ts b/src/providers/urlschemes.ts
index 214a925c4..6617e627e 100644
--- a/src/providers/urlschemes.ts
+++ b/src/providers/urlschemes.ts
@@ -82,6 +82,7 @@ export interface CoreCustomURLSchemesParams {
@Injectable()
export class CoreCustomURLSchemesProvider {
protected logger;
+ protected lastUrls = {};
constructor(logger: CoreLoggerProvider, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider,
private loginHelper: CoreLoginHelperProvider, private linksHelper: CoreContentLinksHelperProvider,
@@ -107,6 +108,15 @@ export class CoreCustomURLSchemesProvider {
isSSOToken = false,
data: CoreCustomURLSchemesParams;
+ /* First check that this URL hasn't been treated a few seconds ago. The function that handles custom URL schemes already
+ does this, but this function is called from other places so we need to handle it in here too. */
+ if (this.lastUrls[url] && Date.now() - this.lastUrls[url] < 3000) {
+ // Function called more than once, stop.
+ return;
+ }
+
+ this.lastUrls[url] = Date.now();
+
// Wait for app to be ready.
return this.initDelegate.ready().then(() => {
url = this.textUtils.decodeURIComponent(url);
@@ -115,6 +125,10 @@ export class CoreCustomURLSchemesProvider {
// Some sites add a # at the end of the URL. If it's there, remove it.
url = url.replace(/\/?#?\/?$/, '');
+ // In iOS, the protocol after the scheme doesn't have ":". Add it.
+ // E.g. "moodlemobile://https://..." is received as "moodlemobile://https//..."
+ url = url.replace(/\/\/(https?)\/\//, '//$1://');
+
modal = this.domUtils.showModalLoading();
// Get the data from the URL.
@@ -268,7 +282,9 @@ export class CoreCustomURLSchemesProvider {
});
}).catch((error) => {
- if (error && isSSOToken) {
+ if (error == 'Duplicated') {
+ // Duplicated request
+ } else if (error && isSSOToken) {
// An error occurred, display the error and logout the user.
this.loginHelper.treatUserTokenError(data.siteUrl, error);
this.sitesProvider.logout();
@@ -426,7 +442,7 @@ export class CoreCustomURLSchemesProvider {
if (this.appProvider.isSSOAuthenticationOngoing()) {
// Authentication ongoing, probably duplicated request.
- return Promise.reject(null);
+ return Promise.reject('Duplicated');
}
if (this.appProvider.isDesktop()) {
@@ -452,7 +468,7 @@ export class CoreCustomURLSchemesProvider {
// Error decoding the parameter.
this.logger.error('Error decoding parameter received for login SSO');
- return null;
+ return Promise.reject(null);
}
return this.loginHelper.validateBrowserSSOLogin(url);
diff --git a/src/providers/utils/dom.ts b/src/providers/utils/dom.ts
index 1af9102c2..4f4fdab17 100644
--- a/src/providers/utils/dom.ts
+++ b/src/providers/utils/dom.ts
@@ -1250,11 +1250,14 @@ export class CoreDomUtilsProvider {
content: text
}),
dismiss = loader.dismiss.bind(loader);
- let isDismissed = false;
+ let isPresented = false,
+ isDismissed = false;
// Override dismiss to prevent dismissing a modal twice (it can throw an error and cause problems).
loader.dismiss = (data, role, navOptions): Promise => {
- if (isDismissed) {
+ if (!isPresented || isDismissed) {
+ isDismissed = true;
+
return Promise.resolve();
}
@@ -1263,7 +1266,13 @@ export class CoreDomUtilsProvider {
return dismiss(data, role, navOptions);
};
- loader.present();
+ // Wait a bit before presenting the modal, to prevent it being displayed if dissmiss is called fast.
+ setTimeout(() => {
+ if (!isDismissed) {
+ isPresented = true;
+ loader.present();
+ }
+ }, 40);
return loader;
}