forked from EVOgeek/Vmeda.Online
		
	Merge pull request #3280 from dpalou/MOBILE-4054
MOBILE-4054 core: Allow not displaying again open file warning
This commit is contained in:
		
						commit
						9fc6ae9b56
					
				| @ -127,7 +127,7 @@ export class CoreLocalFileComponent implements OnInit { | ||||
| 
 | ||||
|         if (!CoreFileHelper.isOpenableInApp(this.file)) { | ||||
|             try { | ||||
|                 await CoreFileHelper.showConfirmOpenUnsupportedFile(); | ||||
|                 await CoreFileHelper.showConfirmOpenUnsupportedFile(false, this.file); | ||||
|             } catch (error) { | ||||
|                 return; // Cancelled, stop.
 | ||||
|             } | ||||
|  | ||||
| @ -163,7 +163,7 @@ export class CoreLinkDirective implements OnInit { | ||||
| 
 | ||||
|         if (!CoreFileHelper.isOpenableInApp({ filename })) { | ||||
|             try { | ||||
|                 await CoreFileHelper.showConfirmOpenUnsupportedFile(); | ||||
|                 await CoreFileHelper.showConfirmOpenUnsupportedFile(false, { filename }); | ||||
|             } catch (error) { | ||||
|                 return; // Cancelled, stop.
 | ||||
|             } | ||||
|  | ||||
| @ -721,7 +721,7 @@ export class CoreCourseHelperProvider { | ||||
|         const mainFile = files[0]; | ||||
| 
 | ||||
|         if (!CoreFileHelper.isOpenableInApp(mainFile)) { | ||||
|             await CoreFileHelper.showConfirmOpenUnsupportedFile(); | ||||
|             await CoreFileHelper.showConfirmOpenUnsupportedFile(false, mainFile); | ||||
|         } | ||||
| 
 | ||||
|         const site = await CoreSites.getSite(siteId); | ||||
|  | ||||
| @ -28,6 +28,8 @@ import { CoreConstants } from '@/core/constants'; | ||||
| import { CoreError } from '@classes/errors/error'; | ||||
| import { makeSingleton, Translate } from '@singletons'; | ||||
| import { CoreNetworkError } from '@classes/errors/network-error'; | ||||
| import { CoreConfig } from './config'; | ||||
| import { CoreCanceledError } from '@classes/errors/cancelederror'; | ||||
| 
 | ||||
| /** | ||||
|  * Provider to provide some helper functions regarding files and packages. | ||||
| @ -71,7 +73,7 @@ export class CoreFileHelperProvider { | ||||
|         const timemodified = this.getFileTimemodified(file); | ||||
| 
 | ||||
|         if (!this.isOpenableInApp(file)) { | ||||
|             await this.showConfirmOpenUnsupportedFile(); | ||||
|             await this.showConfirmOpenUnsupportedFile(false, file); | ||||
|         } | ||||
| 
 | ||||
|         let url = await this.downloadFileIfNeeded( | ||||
| @ -413,13 +415,42 @@ export class CoreFileHelperProvider { | ||||
|      * Show a confirm asking the user if we wants to open the file. | ||||
|      * | ||||
|      * @param onlyDownload Whether the user is only downloading the file, not opening it. | ||||
|      * @param file The file that will be opened. | ||||
|      * @return Promise resolved if confirmed, rejected otherwise. | ||||
|      */ | ||||
|     showConfirmOpenUnsupportedFile(onlyDownload?: boolean): Promise<void> { | ||||
|     async showConfirmOpenUnsupportedFile(onlyDownload = false, file: {filename?: string; name?: string}): Promise<void> { | ||||
|         file = file || {}; // Just in case some plugin doesn't pass it. This can be removed in the future, @since app 4.1.
 | ||||
| 
 | ||||
|         // Check if the user decided not to see the warning.
 | ||||
|         const regex = /(?:\.([^.]+))?$/; | ||||
|         const regexResult = regex.exec(file.filename || file.name || ''); | ||||
| 
 | ||||
|         const configKey = 'CoreFileUnsupportedWarningDisabled-' + (regexResult?.[1] ?? 'unknown'); | ||||
|         const dontShowWarning = await CoreConfig.get(configKey, 0); | ||||
|         if (dontShowWarning) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const message = Translate.instant('core.cannotopeninapp' + (onlyDownload ? 'download' : '')); | ||||
|         const okButton = Translate.instant(onlyDownload ? 'core.downloadfile' : 'core.openfile'); | ||||
| 
 | ||||
|         return CoreDomUtils.showConfirm(message, undefined, okButton, undefined, { cssClass: 'core-modal-force-on-top' }); | ||||
|         try { | ||||
|             const dontShowAgain = await CoreDomUtils.showPrompt( | ||||
|                 message, | ||||
|                 undefined, | ||||
|                 Translate.instant('core.dontshowagain'), | ||||
|                 'checkbox', | ||||
|                 { okText: okButton }, | ||||
|                 { cssClass: 'core-modal-force-on-top' }, | ||||
|             ); | ||||
| 
 | ||||
|             if (dontShowAgain) { | ||||
|                 CoreConfig.set(configKey, 1); | ||||
|             } | ||||
|         } catch { | ||||
|             // User canceled.
 | ||||
|             throw new CoreCanceledError(''); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -1490,7 +1490,8 @@ export class CoreDomUtilsProvider { | ||||
|      * @param header Modal header. | ||||
|      * @param placeholderOrLabel Placeholder (for textual/numeric inputs) or label (for radio/checkbox). By default, "Password". | ||||
|      * @param type Type of the input element. By default, password. | ||||
|      * @param buttons Buttons. If not provided, OK and Cancel buttons will be displayed. | ||||
|      * @param buttons Buttons. If not provided or it's an object with texts, OK and Cancel buttons will be displayed. | ||||
|      * @para options Other alert options. | ||||
|      * @return Promise resolved with the input data (true for checkbox/radio) if the user clicks OK, rejected if cancels. | ||||
|      */ | ||||
|     showPrompt( | ||||
| @ -1498,7 +1499,8 @@ export class CoreDomUtilsProvider { | ||||
|         header?: string, | ||||
|         placeholderOrLabel?: string, | ||||
|         type: TextFieldTypes | 'checkbox' | 'radio' | 'textarea' = 'password', | ||||
|         buttons?: PromptButton[], | ||||
|         buttons?: PromptButton[] | { okText?: string; cancelText?: string }, | ||||
|         options: AlertOptions = {}, | ||||
|     ): Promise<any> { // eslint-disable-line @typescript-eslint/no-explicit-any
 | ||||
|         return new Promise((resolve, reject) => { | ||||
|             placeholderOrLabel = placeholderOrLabel ?? Translate.instant('core.login.password'); | ||||
| @ -1517,10 +1519,9 @@ export class CoreDomUtilsProvider { | ||||
|                 } | ||||
|             }; | ||||
| 
 | ||||
|             const options: AlertOptions = { | ||||
|                 header, | ||||
|                 message, | ||||
|                 inputs: [ | ||||
|             options.header = header; | ||||
|             options.message = message; | ||||
|             options.inputs = [ | ||||
|                 { | ||||
|                     name: 'promptinput', | ||||
|                     placeholder: placeholderOrLabel, | ||||
| @ -1528,10 +1529,9 @@ export class CoreDomUtilsProvider { | ||||
|                     type, | ||||
|                     value: (isCheckbox || isRadio) ? true : undefined, | ||||
|                 }, | ||||
|                 ], | ||||
|             }; | ||||
|             ]; | ||||
| 
 | ||||
|             if (buttons?.length) { | ||||
|             if (Array.isArray(buttons) && buttons.length) { | ||||
|                 options.buttons = buttons.map((button) => ({ | ||||
|                     ...button, | ||||
|                     handler: (data) => { | ||||
| @ -1549,14 +1549,14 @@ export class CoreDomUtilsProvider { | ||||
|                 // Default buttons.
 | ||||
|                 options.buttons = [ | ||||
|                     { | ||||
|                         text: Translate.instant('core.cancel'), | ||||
|                         text: buttons && 'cancelText' in buttons ? buttons.cancelText : Translate.instant('core.cancel'), | ||||
|                         role: 'cancel', | ||||
|                         handler: () => { | ||||
|                             reject(); | ||||
|                         }, | ||||
|                     }, | ||||
|                     { | ||||
|                         text: Translate.instant('core.ok'), | ||||
|                         text: buttons && 'okText' in buttons ? buttons.okText : Translate.instant('core.ok'), | ||||
|                         handler: resolvePromise, | ||||
|                     }, | ||||
|                 ]; | ||||
|  | ||||
| @ -520,7 +520,7 @@ export class CoreIframeUtilsProvider { | ||||
| 
 | ||||
|             if (!CoreFileHelper.isOpenableInApp({ filename })) { | ||||
|                 try { | ||||
|                     await CoreFileHelper.showConfirmOpenUnsupportedFile(); | ||||
|                     await CoreFileHelper.showConfirmOpenUnsupportedFile(false, { filename }); | ||||
|                 } catch (error) { | ||||
|                     return; // Cancelled, stop.
 | ||||
|                 } | ||||
|  | ||||
| @ -91,7 +91,7 @@ export class CoreWindow { | ||||
| 
 | ||||
|             if (!CoreFileHelper.isOpenableInApp({ filename })) { | ||||
|                 try { | ||||
|                     await CoreFileHelper.showConfirmOpenUnsupportedFile(); | ||||
|                     await CoreFileHelper.showConfirmOpenUnsupportedFile(false, { filename }); | ||||
|                 } catch (error) { | ||||
|                     return; // Cancelled, stop.
 | ||||
|                 } | ||||
|  | ||||
							
								
								
									
										58
									
								
								src/tests/behat/open_files.feature
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/tests/behat/open_files.feature
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| @app @javascript | ||||
| Feature: It opens files properly. | ||||
| 
 | ||||
|   Background: | ||||
|     Given the following "users" exist: | ||||
|       | username | | ||||
|       | student1 | | ||||
|     And the following "courses" exist: | ||||
|       | fullname | shortname | | ||||
|       | Course 1 | C1        | | ||||
|     And the following "course enrolments" exist: | ||||
|       | user     | course | role    | | ||||
|       | student1 | C1     | student | | ||||
|     And the following "activities" exist: | ||||
|       | activity | name     | intro                | display | course | defaultfilename | | ||||
|       | resource | Test TXT | Test TXT description | 5       | C1     | A txt.txt       | | ||||
|       | resource | Test RTF | Test RTF description | 5       | C1     | A rtf.rtf       | | ||||
|       | resource | Test DOC | Test DOC description | 5       | C1     | A doc.doc       | | ||||
|     And the following config values are set as admin: | ||||
|       | filetypeexclusionlist | rtf,doc | tool_mobile | | ||||
| 
 | ||||
|   Scenario: Open a file | ||||
|     Given I entered the resource activity "Test TXT" on course "Course 1" as "student1" in the app | ||||
|     When I press "Open" near "Last modified" in the app | ||||
|     Then the app should have opened a browser tab with url "^blob:(first)?" | ||||
| 
 | ||||
|     When I switch to the browser tab opened by the app | ||||
|     Then I should see "Test resource A txt.txt file" | ||||
| 
 | ||||
|     When I close the browser tab opened by the app | ||||
|     And I press the back button in the app | ||||
|     And I press "Test RTF" in the app | ||||
|     And I press "Open" near "Last modified" in the app | ||||
|     Then I should find "This file may not work as expected on this device" in the app | ||||
| 
 | ||||
|     When I press "Open file" in the app | ||||
|     Then the app should have opened a browser tab with url "^blob:(second)?" | ||||
| 
 | ||||
|     When I switch to the browser tab opened by the app | ||||
|     Then I should see "Test resource A rtf.rtf file" | ||||
| 
 | ||||
|     When I close the browser tab opened by the app | ||||
|     And I press "Open" near "Last modified" in the app | ||||
|     Then I should find "This file may not work as expected on this device" in the app | ||||
| 
 | ||||
|     When I select "Don't show again." in the app | ||||
|     And I press "Open file" in the app | ||||
|     Then the app should have opened a browser tab with url "^blob:(third)?" | ||||
| 
 | ||||
|     When I close the browser tab opened by the app | ||||
|     And I press "Open" near "Last modified" in the app | ||||
|     Then the app should have opened a browser tab with url "^blob:(fourth)?" | ||||
| 
 | ||||
|     When I close the browser tab opened by the app | ||||
|     And I press the back button in the app | ||||
|     And I press "Test DOC" in the app | ||||
|     And I press "Open" in the app | ||||
|     Then I should find "This file may not work as expected on this device" in the app | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user