commit
a802df6c3b
|
@ -17,8 +17,8 @@
|
||||||
<core-context-menu-item [hidden]="isSelf || !otherMember || otherMember.isblocked" [priority]="700" [content]="'addon.messages.blockuser' | translate" (action)="blockUser()" [iconAction]="blockIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !otherMember || otherMember.isblocked" [priority]="700" [content]="'addon.messages.blockuser' | translate" (action)="blockUser()" [iconAction]="blockIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.isblocked" [priority]="700" [content]="'addon.messages.unblockuser' | translate" (action)="unblockUser()" [iconAction]="blockIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.isblocked" [priority]="700" [content]="'addon.messages.unblockuser' | translate" (action)="unblockUser()" [iconAction]="blockIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="isSelf || !muteEnabled || !conversation" [priority]="600" [content]="(conversation && conversation.ismuted ? 'addon.messages.unmuteconversation' : 'addon.messages.muteconversation') | translate" (action)="changeMute($event)" [closeOnClick]="false" [iconAction]="muteIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !muteEnabled || !conversation" [priority]="600" [content]="(conversation && conversation.ismuted ? 'addon.messages.unmuteconversation' : 'addon.messages.muteconversation') | translate" (action)="changeMute($event)" [closeOnClick]="false" [iconAction]="muteIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!canDelete" [priority]="400" [content]="'addon.messages.showdeletemessages' | translate" (action)="toggleDelete()" [iconAction]="(showDelete ? 'checkbox-outline' : 'square-outline')"></core-context-menu-item>
|
<core-context-menu-item [hidden]="!canDelete || !messages || !messages.length" [priority]="400" [content]="'addon.messages.showdeletemessages' | translate" (action)="toggleDelete()" [iconAction]="(showDelete ? 'checkbox-outline' : 'square-outline')"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="!groupMessagingEnabled || !conversationId || isGroup" [priority]="200" [content]="'addon.messages.deleteconversation' | translate" (action)="deleteConversation($event)" [closeOnClick]="false" [iconAction]="deleteIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="!groupMessagingEnabled || !conversationId || isGroup || !messages || !messages.length" [priority]="200" [content]="'addon.messages.deleteconversation' | translate" (action)="deleteConversation($event)" [closeOnClick]="false" [iconAction]="deleteIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="isSelf || !otherMember || otherMember.iscontact || requestContactSent || requestContactReceived" [priority]="100" [content]="'addon.messages.addtoyourcontacts' | translate" (action)="createContactRequest()" [iconAction]="addRemoveIcon"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !otherMember || otherMember.iscontact || requestContactSent || requestContactReceived" [priority]="100" [content]="'addon.messages.addtoyourcontacts' | translate" (action)="createContactRequest()" [iconAction]="addRemoveIcon"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.iscontact" [priority]="100" [content]="'addon.messages.removefromyourcontacts' | translate" (action)="removeContact()" [iconAction]="addRemoveIcon" [iconSlash]="true"></core-context-menu-item>
|
<core-context-menu-item [hidden]="isSelf || !otherMember || !otherMember.iscontact" [priority]="100" [content]="'addon.messages.removefromyourcontacts' | translate" (action)="removeContact()" [iconAction]="addRemoveIcon" [iconSlash]="true"></core-context-menu-item>
|
||||||
</core-context-menu>
|
</core-context-menu>
|
||||||
|
|
|
@ -1253,8 +1253,6 @@ export class AddonMessagesDiscussionPage implements OnDestroy {
|
||||||
action: 'delete'
|
action: 'delete'
|
||||||
}, this.siteId);
|
}, this.siteId);
|
||||||
|
|
||||||
this.conversationId = undefined;
|
|
||||||
this.conversation = undefined;
|
|
||||||
this.messages = [];
|
this.messages = [];
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.deleteIcon = 'trash';
|
this.deleteIcon = 'trash';
|
||||||
|
|
|
@ -1010,7 +1010,7 @@ body.keyboard-is-open {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
core-ion-tabs .tabbar {
|
core-ion-tabs[tabsplacement="bottom"] .tabbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,8 +75,8 @@
|
||||||
"notificoncolor": "#f98012",
|
"notificoncolor": "#f98012",
|
||||||
"statusbarbg": false,
|
"statusbarbg": false,
|
||||||
"statusbarlighttext": false,
|
"statusbarlighttext": false,
|
||||||
"statusbarbgios": false,
|
"statusbarbgios": "#f98012",
|
||||||
"statusbarlighttextios": false,
|
"statusbarlighttextios": true,
|
||||||
"statusbarbgandroid": "#df7310",
|
"statusbarbgandroid": "#df7310",
|
||||||
"statusbarlighttextandroid": true,
|
"statusbarlighttextandroid": true,
|
||||||
"statusbarbgremotetheme": "#000000",
|
"statusbarbgremotetheme": "#000000",
|
||||||
|
|
|
@ -10,10 +10,12 @@
|
||||||
<p class="item-heading">{{ 'core.contentlinks.chooseaccounttoopenlink' | translate }}</p>
|
<p class="item-heading">{{ 'core.contentlinks.chooseaccounttoopenlink' | translate }}</p>
|
||||||
<p>{{ url }}</p>
|
<p>{{ url }}</p>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<a ion-item *ngFor="let site of sites" (click)="siteClicked(site.id)">
|
<a ion-item *ngFor="let site of sites" (click)="siteClicked(site.id)" detail-none>
|
||||||
<img [src]="site.avatar" item-start>
|
<ion-avatar item-start>
|
||||||
|
<img [src]="site.avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullname} }}" role="presentation" onError="this.src='assets/img/user-avatar.png'">
|
||||||
|
</ion-avatar>
|
||||||
<h2>{{site.fullName}}</h2>
|
<h2>{{site.fullName}}</h2>
|
||||||
<p><core-format-text clean="true" [text]="site.siteName"></core-format-text></p>
|
<p><core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text></p>
|
||||||
<p>{{site.siteUrl}}</p>
|
<p>{{site.siteUrl}}</p>
|
||||||
</a>
|
</a>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
|
|
|
@ -167,7 +167,10 @@ export class CoreCourseFormatDefaultHandler implements CoreCourseFormatHandler {
|
||||||
Object.assign(params, { course: course });
|
Object.assign(params, { course: course });
|
||||||
|
|
||||||
if (navCtrl) {
|
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 {
|
} else {
|
||||||
// Open the course in the "phantom" tab.
|
// Open the course in the "phantom" tab.
|
||||||
this.loginHelper = this.loginHelper || this.injector.get(CoreLoginHelperProvider);
|
this.loginHelper = this.loginHelper || this.injector.get(CoreLoginHelperProvider);
|
||||||
|
|
|
@ -82,6 +82,7 @@ export interface CoreCustomURLSchemesParams {
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CoreCustomURLSchemesProvider {
|
export class CoreCustomURLSchemesProvider {
|
||||||
protected logger;
|
protected logger;
|
||||||
|
protected lastUrls = {};
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider,
|
constructor(logger: CoreLoggerProvider, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider,
|
||||||
private loginHelper: CoreLoginHelperProvider, private linksHelper: CoreContentLinksHelperProvider,
|
private loginHelper: CoreLoginHelperProvider, private linksHelper: CoreContentLinksHelperProvider,
|
||||||
|
@ -107,6 +108,15 @@ export class CoreCustomURLSchemesProvider {
|
||||||
isSSOToken = false,
|
isSSOToken = false,
|
||||||
data: CoreCustomURLSchemesParams;
|
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.
|
// Wait for app to be ready.
|
||||||
return this.initDelegate.ready().then(() => {
|
return this.initDelegate.ready().then(() => {
|
||||||
url = this.textUtils.decodeURIComponent(url);
|
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.
|
// Some sites add a # at the end of the URL. If it's there, remove it.
|
||||||
url = url.replace(/\/?#?\/?$/, '');
|
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();
|
modal = this.domUtils.showModalLoading();
|
||||||
|
|
||||||
// Get the data from the URL.
|
// Get the data from the URL.
|
||||||
|
@ -268,7 +282,9 @@ export class CoreCustomURLSchemesProvider {
|
||||||
});
|
});
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error && isSSOToken) {
|
if (error == 'Duplicated') {
|
||||||
|
// Duplicated request
|
||||||
|
} else if (error && isSSOToken) {
|
||||||
// An error occurred, display the error and logout the user.
|
// An error occurred, display the error and logout the user.
|
||||||
this.loginHelper.treatUserTokenError(data.siteUrl, error);
|
this.loginHelper.treatUserTokenError(data.siteUrl, error);
|
||||||
this.sitesProvider.logout();
|
this.sitesProvider.logout();
|
||||||
|
@ -426,7 +442,7 @@ export class CoreCustomURLSchemesProvider {
|
||||||
|
|
||||||
if (this.appProvider.isSSOAuthenticationOngoing()) {
|
if (this.appProvider.isSSOAuthenticationOngoing()) {
|
||||||
// Authentication ongoing, probably duplicated request.
|
// Authentication ongoing, probably duplicated request.
|
||||||
return Promise.reject(null);
|
return Promise.reject('Duplicated');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.appProvider.isDesktop()) {
|
if (this.appProvider.isDesktop()) {
|
||||||
|
@ -452,7 +468,7 @@ export class CoreCustomURLSchemesProvider {
|
||||||
// Error decoding the parameter.
|
// Error decoding the parameter.
|
||||||
this.logger.error('Error decoding parameter received for login SSO');
|
this.logger.error('Error decoding parameter received for login SSO');
|
||||||
|
|
||||||
return null;
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.loginHelper.validateBrowserSSOLogin(url);
|
return this.loginHelper.validateBrowserSSOLogin(url);
|
||||||
|
|
|
@ -1250,11 +1250,14 @@ export class CoreDomUtilsProvider {
|
||||||
content: text
|
content: text
|
||||||
}),
|
}),
|
||||||
dismiss = loader.dismiss.bind(loader);
|
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).
|
// Override dismiss to prevent dismissing a modal twice (it can throw an error and cause problems).
|
||||||
loader.dismiss = (data, role, navOptions): Promise<any> => {
|
loader.dismiss = (data, role, navOptions): Promise<any> => {
|
||||||
if (isDismissed) {
|
if (!isPresented || isDismissed) {
|
||||||
|
isDismissed = true;
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1263,7 +1266,13 @@ export class CoreDomUtilsProvider {
|
||||||
return dismiss(data, role, navOptions);
|
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;
|
return loader;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue