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.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]="!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]="!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]="!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 || !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" [priority]="100" [content]="'addon.messages.removefromyourcontacts' | translate" (action)="removeContact()" [iconAction]="addRemoveIcon" [iconSlash]="true"></core-context-menu-item> | ||||
|         </core-context-menu> | ||||
|  | ||||
| @ -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'; | ||||
|  | ||||
| @ -1010,7 +1010,7 @@ body.keyboard-is-open { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   core-ion-tabs .tabbar { | ||||
|   core-ion-tabs[tabsplacement="bottom"] .tabbar { | ||||
|       display: none; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -75,8 +75,8 @@ | ||||
|     "notificoncolor": "#f98012", | ||||
|     "statusbarbg": false, | ||||
|     "statusbarlighttext": false, | ||||
|     "statusbarbgios": false, | ||||
|     "statusbarlighttextios": false, | ||||
|     "statusbarbgios": "#f98012", | ||||
|     "statusbarlighttextios": true, | ||||
|     "statusbarbgandroid": "#df7310", | ||||
|     "statusbarlighttextandroid": true, | ||||
|     "statusbarbgremotetheme": "#000000", | ||||
|  | ||||
| @ -10,10 +10,12 @@ | ||||
|                 <p class="item-heading">{{ 'core.contentlinks.chooseaccounttoopenlink' | translate }}</p> | ||||
|                 <p>{{ url }}</p> | ||||
|             </ion-item> | ||||
|             <a ion-item *ngFor="let site of sites" (click)="siteClicked(site.id)"> | ||||
|                 <img [src]="site.avatar" item-start> | ||||
|             <a ion-item *ngFor="let site of sites" (click)="siteClicked(site.id)" detail-none> | ||||
|                 <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> | ||||
|                 <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> | ||||
|             </a> | ||||
|             <ion-item> | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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<any> => { | ||||
|             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; | ||||
|     } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user