forked from EVOgeek/Vmeda.Online
		
	
						commit
						6d0d3248b1
					
				
							
								
								
									
										248
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										248
									
								
								package.json
									
									
									
									
									
								
							| @ -33,141 +33,141 @@ | |||||||
|     "ionic:build:before": "gulp" |     "ionic:build:before": "gulp" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@angular/animations": "^11.0.1", |     "@angular/animations": "11.0.1", | ||||||
|     "@angular/common": "~10.0.0", |     "@angular/common": "10.0.14", | ||||||
|     "@angular/core": "~10.0.0", |     "@angular/core": "10.0.14", | ||||||
|     "@angular/forms": "~10.0.0", |     "@angular/forms": "10.0.14", | ||||||
|     "@angular/platform-browser": "~10.0.0", |     "@angular/platform-browser": "10.0.14", | ||||||
|     "@angular/platform-browser-dynamic": "~10.0.0", |     "@angular/platform-browser-dynamic": "10.0.14", | ||||||
|     "@angular/router": "~10.0.0", |     "@angular/router": "10.0.14", | ||||||
|     "@ionic-native/badge": "^5.33.0", |     "@ionic-native/badge": "5.33.0", | ||||||
|     "@ionic-native/camera": "^5.33.0", |     "@ionic-native/camera": "5.33.0", | ||||||
|     "@ionic-native/chooser": "^5.33.0", |     "@ionic-native/chooser": "5.33.0", | ||||||
|     "@ionic-native/clipboard": "^5.33.0", |     "@ionic-native/clipboard": "5.33.0", | ||||||
|     "@ionic-native/core": "^5.33.0", |     "@ionic-native/core": "5.33.0", | ||||||
|     "@ionic-native/device": "^5.33.0", |     "@ionic-native/device": "5.33.0", | ||||||
|     "@ionic-native/diagnostic": "^5.33.0", |     "@ionic-native/diagnostic": "5.33.0", | ||||||
|     "@ionic-native/file": "^5.33.0", |     "@ionic-native/file": "5.33.0", | ||||||
|     "@ionic-native/file-opener": "^5.33.0", |     "@ionic-native/file-opener": "5.33.0", | ||||||
|     "@ionic-native/file-transfer": "^5.33.0", |     "@ionic-native/file-transfer": "5.33.0", | ||||||
|     "@ionic-native/geolocation": "^5.33.0", |     "@ionic-native/geolocation": "5.33.0", | ||||||
|     "@ionic-native/http": "^5.33.0", |     "@ionic-native/http": "5.33.0", | ||||||
|     "@ionic-native/in-app-browser": "^5.33.0", |     "@ionic-native/in-app-browser": "5.33.0", | ||||||
|     "@ionic-native/ionic-webview": "^5.33.0", |     "@ionic-native/ionic-webview": "5.33.0", | ||||||
|     "@ionic-native/keyboard": "^5.33.0", |     "@ionic-native/keyboard": "5.33.0", | ||||||
|     "@ionic-native/local-notifications": "^5.33.0", |     "@ionic-native/local-notifications": "5.33.0", | ||||||
|     "@ionic-native/media": "^5.33.0", |     "@ionic-native/media": "5.33.0", | ||||||
|     "@ionic-native/media-capture": "^5.33.0", |     "@ionic-native/media-capture": "5.33.0", | ||||||
|     "@ionic-native/network": "^5.33.0", |     "@ionic-native/network": "5.33.0", | ||||||
|     "@ionic-native/push": "^5.33.0", |     "@ionic-native/push": "5.33.0", | ||||||
|     "@ionic-native/qr-scanner": "^5.33.0", |     "@ionic-native/qr-scanner": "5.33.0", | ||||||
|     "@ionic-native/splash-screen": "^5.33.0", |     "@ionic-native/splash-screen": "5.33.0", | ||||||
|     "@ionic-native/sqlite": "^5.33.0", |     "@ionic-native/sqlite": "5.33.0", | ||||||
|     "@ionic-native/status-bar": "^5.33.0", |     "@ionic-native/status-bar": "5.33.0", | ||||||
|     "@ionic-native/web-intent": "^5.33.0", |     "@ionic-native/web-intent": "5.33.0", | ||||||
|     "@ionic-native/zip": "^5.33.0", |     "@ionic-native/zip": "5.33.0", | ||||||
|     "@ionic/angular": "^5.6.6", |     "@ionic/angular": "5.6.6", | ||||||
|     "@ngx-translate/core": "^13.0.0", |     "@ngx-translate/core": "13.0.0", | ||||||
|     "@ngx-translate/http-loader": "^6.0.0", |     "@ngx-translate/http-loader": "6.0.0", | ||||||
|     "@types/chart.js": "^2.9.31", |     "@types/chart.js": "2.9.31", | ||||||
|     "@types/cordova": "0.0.34", |     "@types/cordova": "0.0.34", | ||||||
|     "@types/cordova-plugin-file-transfer": "^1.6.2", |     "@types/cordova-plugin-file-transfer": "1.6.2", | ||||||
|     "@types/dom-mediacapture-record": "^1.0.7", |     "@types/dom-mediacapture-record": "1.0.7", | ||||||
|     "chart.js": "^2.9.4", |     "chart.js": "2.9.4", | ||||||
|     "com-darryncampbell-cordova-plugin-intent": "^1.3.0", |     "com-darryncampbell-cordova-plugin-intent": "1.3.0", | ||||||
|     "cordova": "^10.0.0", |     "cordova": "10.0.0", | ||||||
|     "cordova-android": "^9.1.0", |     "cordova-android": "9.1.0", | ||||||
|     "cordova-android-support-gradle-release": "^3.0.1", |     "cordova-android-support-gradle-release": "3.0.1", | ||||||
|     "cordova-clipboard": "^1.3.0", |     "cordova-clipboard": "1.3.0", | ||||||
|     "cordova-ios": "^6.2.0", |     "cordova-ios": "6.2.0", | ||||||
|     "cordova-plugin-add-swift-support": "^2.0.2", |     "cordova-plugin-add-swift-support": "2.0.2", | ||||||
|     "cordova-plugin-advanced-http": "^3.1.0", |     "cordova-plugin-advanced-http": "3.1.0", | ||||||
|     "cordova-plugin-badge": "^0.8.8", |     "cordova-plugin-badge": "0.8.8", | ||||||
|     "cordova-plugin-camera": "^5.0.1", |     "cordova-plugin-camera": "5.0.1", | ||||||
|     "cordova-plugin-chooser": "^1.3.2", |     "cordova-plugin-chooser": "1.3.2", | ||||||
|     "cordova-plugin-customurlscheme": "^5.0.2", |     "cordova-plugin-customurlscheme": "5.0.2", | ||||||
|     "cordova-plugin-device": "^2.0.3", |     "cordova-plugin-device": "2.0.3", | ||||||
|     "cordova-plugin-file": "^6.0.2", |     "cordova-plugin-file": "6.0.2", | ||||||
|     "cordova-plugin-file-opener2": "^3.0.5", |     "cordova-plugin-file-opener2": "3.0.5", | ||||||
|     "cordova-plugin-file-transfer": "git+https://github.com/moodlemobile/cordova-plugin-file-transfer.git", |     "cordova-plugin-file-transfer": "git+https://github.com/moodlemobile/cordova-plugin-file-transfer.git", | ||||||
|     "cordova-plugin-geolocation": "^4.1.0", |     "cordova-plugin-geolocation": "4.1.0", | ||||||
|     "cordova-plugin-globalization": "^1.11.0", |     "cordova-plugin-globalization": "1.11.0", | ||||||
|     "cordova-plugin-inappbrowser": "^5.0.0", |     "cordova-plugin-inappbrowser": "5.0.0", | ||||||
|     "cordova-plugin-ionic-keyboard": "^2.2.0", |     "cordova-plugin-ionic-keyboard": "2.2.0", | ||||||
|     "cordova-plugin-ionic-webview": "^5.0.0", |     "cordova-plugin-ionic-webview": "5.0.0", | ||||||
|     "cordova-plugin-local-notification": "git+https://github.com/moodlemobile/cordova-plugin-local-notification.git#moodle", |     "cordova-plugin-local-notification": "git+https://github.com/moodlemobile/cordova-plugin-local-notification.git#moodle", | ||||||
|     "cordova-plugin-media": "^5.0.3", |     "cordova-plugin-media": "5.0.3", | ||||||
|     "cordova-plugin-media-capture": "^3.0.3", |     "cordova-plugin-media-capture": "3.0.3", | ||||||
|     "cordova-plugin-network-information": "^2.0.2", |     "cordova-plugin-network-information": "2.0.2", | ||||||
|     "cordova-plugin-qrscanner": "git+https://github.com/moodlemobile/cordova-plugin-qrscanner.git#dist", |     "cordova-plugin-qrscanner": "git+https://github.com/moodlemobile/cordova-plugin-qrscanner.git#dist", | ||||||
|     "cordova-plugin-screen-orientation": "^3.0.2", |     "cordova-plugin-screen-orientation": "3.0.2", | ||||||
|     "cordova-plugin-splashscreen": "^6.0.0", |     "cordova-plugin-splashscreen": "6.0.0", | ||||||
|     "cordova-plugin-statusbar": "^2.4.3", |     "cordova-plugin-statusbar": "2.4.3", | ||||||
|     "cordova-plugin-whitelist": "^1.3.4", |     "cordova-plugin-whitelist": "1.3.4", | ||||||
|     "cordova-plugin-wkuserscript": "git+https://github.com/moodlemobile/cordova-plugin-wkuserscript.git", |     "cordova-plugin-wkuserscript": "git+https://github.com/moodlemobile/cordova-plugin-wkuserscript.git", | ||||||
|     "cordova-plugin-wkwebview-cookies": "git+https://github.com/moodlemobile/cordova-plugin-wkwebview-cookies.git", |     "cordova-plugin-wkwebview-cookies": "git+https://github.com/moodlemobile/cordova-plugin-wkwebview-cookies.git", | ||||||
|     "cordova-plugin-zip": "^3.1.0", |     "cordova-plugin-zip": "3.1.0", | ||||||
|     "cordova-sqlite-storage": "^6.0.0", |     "cordova-sqlite-storage": "6.0.0", | ||||||
|     "cordova-support-google-services": "^1.2.1", |     "cordova-support-google-services": "1.3.2", | ||||||
|     "cordova.plugins.diagnostic": "^5.0.2", |     "cordova.plugins.diagnostic": "5.0.2", | ||||||
|     "core-js": "^3.9.1", |     "core-js": "3.9.1", | ||||||
|     "es6-promise-plugin": "^4.2.2", |     "es6-promise-plugin": "4.2.2", | ||||||
|     "jszip": "^3.5.0", |     "jszip": "3.5.0", | ||||||
|     "mathjax": "2.7.7", |     "mathjax": "2.7.7", | ||||||
|     "moment": "^2.29.0", |     "moment": "2.29.0", | ||||||
|     "nl.kingsquare.cordova.background-audio": "^1.0.1", |     "nl.kingsquare.cordova.background-audio": "1.0.1", | ||||||
|     "phonegap-plugin-multidex": "^1.0.0", |     "phonegap-plugin-multidex": "1.0.0", | ||||||
|     "phonegap-plugin-push": "git+https://github.com/moodlemobile/phonegap-plugin-push.git#moodle-v3", |     "phonegap-plugin-push": "git+https://github.com/moodlemobile/phonegap-plugin-push.git#moodle-v3", | ||||||
|     "rxjs": "~6.5.5", |     "rxjs": "6.5.5", | ||||||
|     "ts-md5": "^1.2.7", |     "ts-md5": "1.2.7", | ||||||
|     "tslib": "^2.0.0", |     "tslib": "2.0.1", | ||||||
|     "zone.js": "~0.10.3" |     "zone.js": "0.10.3" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@angular-devkit/architect": "^0.1101.2", |     "@angular-devkit/architect": "0.1101.2", | ||||||
|     "@angular-devkit/build-angular": "~0.1000.0", |     "@angular-devkit/build-angular": "0.1000.8", | ||||||
|     "@angular-eslint/builder": "^4.2.0", |     "@angular-eslint/builder": "4.2.0", | ||||||
|     "@angular-eslint/eslint-plugin": "^4.2.0", |     "@angular-eslint/eslint-plugin": "4.2.0", | ||||||
|     "@angular-eslint/eslint-plugin-template": "^4.2.0", |     "@angular-eslint/eslint-plugin-template": "4.2.0", | ||||||
|     "@angular-eslint/schematics": "^4.2.0", |     "@angular-eslint/schematics": "4.2.0", | ||||||
|     "@angular-eslint/template-parser": "^4.2.0", |     "@angular-eslint/template-parser": "4.2.0", | ||||||
|     "@angular/cli": "~10.0.5", |     "@angular/cli": "10.0.8", | ||||||
|     "@angular/compiler": "~10.0.0", |     "@angular/compiler": "10.0.14", | ||||||
|     "@angular/compiler-cli": "~10.0.0", |     "@angular/compiler-cli": "10.0.14", | ||||||
|     "@angular/language-service": "~10.0.0", |     "@angular/language-service": "10.0.14", | ||||||
|     "@ionic/angular-toolkit": "^2.3.0", |     "@ionic/angular-toolkit": "2.3.3", | ||||||
|     "@ionic/cli": "^6.14.1", |     "@ionic/cli": "6.14.1", | ||||||
|     "@types/faker": "^5.1.3", |     "@types/faker": "5.1.3", | ||||||
|     "@types/node": "^12.12.64", |     "@types/node": "12.12.64", | ||||||
|     "@types/resize-observer-browser": "^0.1.5", |     "@types/resize-observer-browser": "0.1.5", | ||||||
|     "@types/webpack-env": "^1.16.0", |     "@types/webpack-env": "1.16.0", | ||||||
|     "@typescript-eslint/eslint-plugin": "^4.22.0", |     "@typescript-eslint/eslint-plugin": "4.22.0", | ||||||
|     "@typescript-eslint/parser": "^4.22.0", |     "@typescript-eslint/parser": "4.22.0", | ||||||
|     "check-es-compat": "^1.1.1", |     "check-es-compat": "1.1.1", | ||||||
|     "cordova-plugin-prevent-override": "git+https://github.com/moodlemobile/cordova-plugin-prevent-override.git", |     "cordova-plugin-prevent-override": "git+https://github.com/moodlemobile/cordova-plugin-prevent-override.git", | ||||||
|     "eslint": "^7.25.0", |     "eslint": "7.25.0", | ||||||
|     "eslint-config-prettier": "^8.3.0", |     "eslint-config-prettier": "8.3.0", | ||||||
|     "eslint-plugin-header": "^3.1.1", |     "eslint-plugin-header": "3.1.1", | ||||||
|     "eslint-plugin-import": "^2.22.1", |     "eslint-plugin-import": "2.22.1", | ||||||
|     "eslint-plugin-jest": "^24.3.6", |     "eslint-plugin-jest": "24.3.6", | ||||||
|     "eslint-plugin-jsdoc": "^32.3.3", |     "eslint-plugin-jsdoc": "32.3.3", | ||||||
|     "eslint-plugin-prefer-arrow": "^1.2.3", |     "eslint-plugin-prefer-arrow": "1.2.3", | ||||||
|     "eslint-plugin-promise": "^5.1.0", |     "eslint-plugin-promise": "5.1.0", | ||||||
|     "faker": "^5.1.0", |     "faker": "5.1.0", | ||||||
|     "fs-extra": "^9.1.0", |     "fs-extra": "9.1.0", | ||||||
|     "gulp": "4.0.2", |     "gulp": "4.0.2", | ||||||
|     "gulp-clip-empty-files": "^0.1.2", |     "gulp-clip-empty-files": "0.1.2", | ||||||
|     "gulp-concat": "^2.6.1", |     "gulp-concat": "2.6.1", | ||||||
|     "gulp-flatten": "^0.4.0", |     "gulp-flatten": "0.4.0", | ||||||
|     "gulp-htmlmin": "^5.0.1", |     "gulp-htmlmin": "5.0.1", | ||||||
|     "gulp-rename": "^2.0.0", |     "gulp-rename": "2.0.0", | ||||||
|     "gulp-slash": "^1.1.3", |     "gulp-slash": "1.1.3", | ||||||
|     "jest": "^26.5.0", |     "jest": "26.5.2", | ||||||
|     "jest-preset-angular": "^8.3.1", |     "jest-preset-angular": "8.3.1", | ||||||
|     "jsonc-parser": "^2.3.1", |     "jsonc-parser": "2.3.1", | ||||||
|     "ts-jest": "^26.4.1", |     "ts-jest": "26.4.1", | ||||||
|     "ts-node": "~8.3.0", |     "ts-node": "8.3.0", | ||||||
|     "typescript": "^3.9.9" |     "typescript": "3.9.9" | ||||||
|   }, |   }, | ||||||
|   "engines": { |   "engines": { | ||||||
|     "node": ">=12.x" |     "node": ">=12.x" | ||||||
| @ -236,6 +236,6 @@ | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "optionalDependencies": { |   "optionalDependencies": { | ||||||
|     "keytar": "^7.2.0" |     "keytar": "7.2.0" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1993,6 +1993,7 @@ | |||||||
|   "core.percentagenumber": "local_moodlemobileapp", |   "core.percentagenumber": "local_moodlemobileapp", | ||||||
|   "core.phone": "moodle", |   "core.phone": "moodle", | ||||||
|   "core.pictureof": "moodle", |   "core.pictureof": "moodle", | ||||||
|  |   "core.play": "local_moodlemobileapp", | ||||||
|   "core.previous": "moodle", |   "core.previous": "moodle", | ||||||
|   "core.proceed": "moodle", |   "core.proceed": "moodle", | ||||||
|   "core.pulltorefresh": "local_moodlemobileapp", |   "core.pulltorefresh": "local_moodlemobileapp", | ||||||
|  | |||||||
| @ -40,6 +40,8 @@ export class AddonModFolderIndexPage extends CoreCourseModuleMainActivityPage<Ad | |||||||
|         super.ngOnInit(); |         super.ngOnInit(); | ||||||
|         this.folderInstance = CoreNavigator.getRouteParam<AddonModFolderFolder>('folderInstance'); |         this.folderInstance = CoreNavigator.getRouteParam<AddonModFolderFolder>('folderInstance'); | ||||||
|         this.subfolder = CoreNavigator.getRouteParam<AddonModFolderFolderFormattedData>('subfolder'); |         this.subfolder = CoreNavigator.getRouteParam<AddonModFolderFolderFormattedData>('subfolder'); | ||||||
|  | 
 | ||||||
|  |         this.title = this.subfolder?.filename || this.module.name; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -259,6 +259,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges | |||||||
|                 forum: this.forum, |                 forum: this.forum, | ||||||
|             }, |             }, | ||||||
|             backdropDismiss: false, |             backdropDismiss: false, | ||||||
|  |             cssClass: 'core-modal-fullscreen', | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         if (!modalData) { |         if (!modalData) { | ||||||
|  | |||||||
| @ -47,11 +47,18 @@ | |||||||
| 
 | 
 | ||||||
|     <ng-container *ngIf="mode == 'external'"> |     <ng-container *ngIf="mode == 'external'"> | ||||||
|         <ion-button expand="block" class="ion-margin" (click)="open(openFileAction.OPEN)"> |         <ion-button expand="block" class="ion-margin" (click)="open(openFileAction.OPEN)"> | ||||||
|  |             <ng-container *ngIf="isStreamedFile"> | ||||||
|  |                 <ion-icon name="fas-play" slot="start" aria-hidden="true"></ion-icon> | ||||||
|  |                 {{ 'core.play' | translate }} | ||||||
|  |             </ng-container> | ||||||
|  |             <ng-container *ngIf="!isStreamedFile"> | ||||||
|                 <ion-icon name="far-file" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon name="far-file" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 {{ 'addon.mod_resource.openthefile' | translate }} |                 {{ 'addon.mod_resource.openthefile' | translate }} | ||||||
|  |             </ng-container> | ||||||
|         </ion-button> |         </ion-button> | ||||||
| 
 | 
 | ||||||
|         <ion-button *ngIf="isIOS" expand="block" class="ion-margin" (click)="open(openFileAction.OPEN_WITH)"> |         <ion-button *ngIf="isIOS && (!shouldOpenInBrowser || !isOnline)" expand="block" class="ion-margin" | ||||||
|  |             (click)="open(openFileAction.OPEN_WITH)"> | ||||||
|             <ion-icon name="far-share-square" slot="start" aria-hidden="true"></ion-icon> |             <ion-icon name="far-share-square" slot="start" aria-hidden="true"></ion-icon> | ||||||
|             {{ 'core.openwith' | translate }} |             {{ 'core.openwith' | translate }} | ||||||
|         </ion-button> |         </ion-button> | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ | |||||||
| // See the License for the specific language governing permissions and
 | // See the License for the specific language governing permissions and
 | ||||||
| // limitations under the License.
 | // limitations under the License.
 | ||||||
| 
 | 
 | ||||||
| import { Component, OnInit, Optional } from '@angular/core'; | import { Component, OnDestroy, OnInit, Optional } from '@angular/core'; | ||||||
| import { CoreError } from '@classes/errors/error'; | import { CoreError } from '@classes/errors/error'; | ||||||
| import { | import { | ||||||
|     CoreCourseModuleMainResourceComponent, |     CoreCourseModuleMainResourceComponent, | ||||||
| @ -21,10 +21,13 @@ import { CoreCourseContentsPage } from '@features/course/pages/contents/contents | |||||||
| import { CoreCourse, CoreCourseWSModule } from '@features/course/services/course'; | import { CoreCourse, CoreCourseWSModule } from '@features/course/services/course'; | ||||||
| import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; | import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; | ||||||
| import { CoreApp } from '@services/app'; | import { CoreApp } from '@services/app'; | ||||||
|  | import { CoreFileHelper } from '@services/file-helper'; | ||||||
| import { CoreSites } from '@services/sites'; | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreMimetypeUtils } from '@services/utils/mimetype'; | ||||||
| import { CoreTextUtils } from '@services/utils/text'; | import { CoreTextUtils } from '@services/utils/text'; | ||||||
| import { CoreUtils, OpenFileAction } from '@services/utils/utils'; | import { CoreUtils, OpenFileAction } from '@services/utils/utils'; | ||||||
| import { Translate } from '@singletons'; | import { Network, NgZone, Translate } from '@singletons'; | ||||||
|  | import { Subscription } from 'rxjs'; | ||||||
| import { | import { | ||||||
|     AddonModResource, |     AddonModResource, | ||||||
|     AddonModResourceCustomData, |     AddonModResourceCustomData, | ||||||
| @ -40,7 +43,7 @@ import { AddonModResourceHelper } from '../../services/resource-helper'; | |||||||
|     selector: 'addon-mod-resource-index', |     selector: 'addon-mod-resource-index', | ||||||
|     templateUrl: 'addon-mod-resource-index.html', |     templateUrl: 'addon-mod-resource-index.html', | ||||||
| }) | }) | ||||||
| export class AddonModResourceIndexComponent extends CoreCourseModuleMainResourceComponent implements OnInit { | export class AddonModResourceIndexComponent extends CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy { | ||||||
| 
 | 
 | ||||||
|     component = AddonModResourceProvider.COMPONENT; |     component = AddonModResourceProvider.COMPONENT; | ||||||
| 
 | 
 | ||||||
| @ -52,19 +55,35 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource | |||||||
|     warning = ''; |     warning = ''; | ||||||
|     isIOS = false; |     isIOS = false; | ||||||
|     openFileAction = OpenFileAction; |     openFileAction = OpenFileAction; | ||||||
|  |     isOnline = false; | ||||||
|  |     isStreamedFile = false; | ||||||
|  |     shouldOpenInBrowser = false; | ||||||
|  | 
 | ||||||
|  |     protected onlineObserver?: Subscription; | ||||||
| 
 | 
 | ||||||
|     constructor(@Optional() courseContentsPage?: CoreCourseContentsPage) { |     constructor(@Optional() courseContentsPage?: CoreCourseContentsPage) { | ||||||
|         super('AddonModResourceIndexComponent', courseContentsPage); |         super('AddonModResourceIndexComponent', courseContentsPage); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Component being initialized. |      * @inheritdoc | ||||||
|      */ |      */ | ||||||
|     async ngOnInit(): Promise<void> { |     async ngOnInit(): Promise<void> { | ||||||
|         super.ngOnInit(); |         super.ngOnInit(); | ||||||
| 
 | 
 | ||||||
|         this.canGetResource = AddonModResource.isGetResourceWSAvailable(); |         this.canGetResource = AddonModResource.isGetResourceWSAvailable(); | ||||||
|         this.isIOS = CoreApp.isIOS(); |         this.isIOS = CoreApp.isIOS(); | ||||||
|  |         this.isOnline = CoreApp.isOnline(); | ||||||
|  | 
 | ||||||
|  |         if (this.isIOS) { | ||||||
|  |             // Refresh online status when changes.
 | ||||||
|  |             this.onlineObserver = Network.onChange().subscribe(() => { | ||||||
|  |                 // Execute the callback in the Angular zone, so change detection doesn't stop working.
 | ||||||
|  |                 NgZone.run(() => { | ||||||
|  |                     this.isOnline = CoreApp.isOnline(); | ||||||
|  |                 }); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         await this.loadContent(); |         await this.loadContent(); | ||||||
|         try { |         try { | ||||||
| @ -76,19 +95,14 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Perform the invalidate content function. |      * @inheritdoc | ||||||
|      * |  | ||||||
|      * @return Resolved when done. |  | ||||||
|      */ |      */ | ||||||
|     protected async invalidateContent(): Promise<void> { |     protected async invalidateContent(): Promise<void> { | ||||||
|         return AddonModResource.invalidateContent(this.module.id, this.courseId); |         return AddonModResource.invalidateContent(this.module.id, this.courseId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Download resource contents. |      * @inheritdoc | ||||||
|      * |  | ||||||
|      * @param refresh Whether we're refreshing data. |  | ||||||
|      * @return Promise resolved when done. |  | ||||||
|      */ |      */ | ||||||
|     protected async fetchContent(refresh?: boolean): Promise<void> { |     protected async fetchContent(refresh?: boolean): Promise<void> { | ||||||
|         // Load module contents if needed. Passing refresh is needed to force reloading contents.
 |         // Load module contents if needed. Passing refresh is needed to force reloading contents.
 | ||||||
| @ -150,6 +164,14 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource | |||||||
|             } else { |             } else { | ||||||
|                 this.mode = 'external'; |                 this.mode = 'external'; | ||||||
|                 this.warning = ''; |                 this.warning = ''; | ||||||
|  | 
 | ||||||
|  |                 if (this.isIOS) { | ||||||
|  |                     this.shouldOpenInBrowser = CoreFileHelper.shouldOpenInBrowser(this.module.contents[0]); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 const mimetype = await CoreUtils.getMimeTypeFromUrl(CoreFileHelper.getFileUrl(this.module.contents[0])); | ||||||
|  | 
 | ||||||
|  |                 this.isStreamedFile = CoreMimetypeUtils.isStreamedMimetype(mimetype); | ||||||
|             } |             } | ||||||
|         } finally { |         } finally { | ||||||
|             this.fillContextMenu(refresh); |             this.fillContextMenu(refresh); | ||||||
| @ -179,4 +201,12 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource | |||||||
|         await CoreSites.getCurrentSite()?.openInBrowserWithAutoLoginIfSameSite(this.module.url!); |         await CoreSites.getCurrentSite()?.openInBrowserWithAutoLoginIfSameSite(this.module.url!); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * @inheritdoc | ||||||
|  |      */ | ||||||
|  |     ngOnDestroy(): void { | ||||||
|  |         super.ngOnDestroy(); | ||||||
|  |         this.onlineObserver?.unsubscribe(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ | |||||||
|             [canTrustDownload]="!alwaysDownload" (action)="download()" size="small"> |             [canTrustDownload]="!alwaysDownload" (action)="download()" size="small"> | ||||||
|         </core-download-refresh> |         </core-download-refresh> | ||||||
| 
 | 
 | ||||||
|         <ion-button fill="clear" *ngIf="isDownloaded && isIOS" (click)="openFile(true)" color="dark" |         <ion-button fill="clear" *ngIf="isDownloaded && isIOS" (click)="openFile($event, true)" color="dark" | ||||||
|             [title]="openButtonLabel | translate"> |             [title]="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> | ||||||
|  | |||||||
| @ -144,10 +144,14 @@ export class CoreFileComponent implements OnInit, OnDestroy { | |||||||
|     /** |     /** | ||||||
|      * Convenience function to open a file, downloading it if needed. |      * Convenience function to open a file, downloading it if needed. | ||||||
|      * |      * | ||||||
|  |      * @param ev Click event (if any). | ||||||
|      * @param isOpenButton Whether the open button was clicked. |      * @param isOpenButton Whether the open button was clicked. | ||||||
|      * @return Promise resolved when file is opened. |      * @return Promise resolved when file is opened. | ||||||
|      */ |      */ | ||||||
|     openFile(isOpenButton = false): Promise<void> { |     openFile(ev?: Event, isOpenButton = false): Promise<void> { | ||||||
|  |         ev?.preventDefault(); | ||||||
|  |         ev?.stopPropagation(); | ||||||
|  | 
 | ||||||
|         const options: CoreUtilsOpenFileOptions = {}; |         const options: CoreUtilsOpenFileOptions = {}; | ||||||
|         if (isOpenButton) { |         if (isOpenButton) { | ||||||
|             // Use the non-default method.
 |             // Use the non-default method.
 | ||||||
|  | |||||||
| @ -117,7 +117,7 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck { | |||||||
|     // eslint-disable-next-line @angular-eslint/no-conflicting-lifecycle
 |     // eslint-disable-next-line @angular-eslint/no-conflicting-lifecycle
 | ||||||
|     async ngOnChanges(changes: Record<string, SimpleChange>): Promise<void> { |     async ngOnChanges(changes: Record<string, SimpleChange>): Promise<void> { | ||||||
|         // Only compile if text/javascript has changed or the forceCompile flag has been set to true.
 |         // Only compile if text/javascript has changed or the forceCompile flag has been set to true.
 | ||||||
|         if (this.text && (changes.text || changes.javascript || |         if (this.text !== undefined && (changes.text || changes.javascript || | ||||||
|                 (changes.forceCompile && CoreUtils.isTrueOrOne(this.forceCompile)))) { |                 (changes.forceCompile && CoreUtils.isTrueOrOne(this.forceCompile)))) { | ||||||
| 
 | 
 | ||||||
|             // Create a new component and a new module.
 |             // Create a new component and a new module.
 | ||||||
|  | |||||||
| @ -681,21 +681,29 @@ export class CoreCourseHelperProvider { | |||||||
|             throw new CoreError(Translate.instant('core.filenotfound')); |             throw new CoreError(Translate.instant('core.filenotfound')); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!CoreFileHelper.isOpenableInApp(module.contents[0])) { |         const mainFile = files[0]; | ||||||
|  | 
 | ||||||
|  |         if (!CoreFileHelper.isOpenableInApp(mainFile)) { | ||||||
|             await CoreFileHelper.showConfirmOpenUnsupportedFile(); |             await CoreFileHelper.showConfirmOpenUnsupportedFile(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const site = await CoreSites.getSite(siteId); |         const site = await CoreSites.getSite(siteId); | ||||||
| 
 | 
 | ||||||
|         const mainFile = files[0]; |  | ||||||
| 
 |  | ||||||
|         // Check if the file should be opened in browser.
 |         // Check if the file should be opened in browser.
 | ||||||
|         if (CoreFileHelper.shouldOpenInBrowser(mainFile)) { |         if (CoreFileHelper.shouldOpenInBrowser(mainFile)) { | ||||||
|             return this.openModuleFileInBrowser(mainFile.fileurl, site, module, courseId, component, componentId, files); |             return this.openModuleFileInBrowser(mainFile.fileurl, site, module, courseId, component, componentId, files, options); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // File shouldn't be opened in browser. Download the module if it needs to be downloaded.
 |         // File shouldn't be opened in browser. Download the module if it needs to be downloaded.
 | ||||||
|         const result = await this.downloadModuleWithMainFileIfNeeded(module, courseId, component || '', componentId, files, siteId); |         const result = await this.downloadModuleWithMainFileIfNeeded( | ||||||
|  |             module, | ||||||
|  |             courseId, | ||||||
|  |             component || '', | ||||||
|  |             componentId, | ||||||
|  |             files, | ||||||
|  |             siteId, | ||||||
|  |             options, | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         if (CoreUrlUtils.isLocalFileUrl(result.path)) { |         if (CoreUrlUtils.isLocalFileUrl(result.path)) { | ||||||
|             return CoreUtils.openFile(result.path, options); |             return CoreUtils.openFile(result.path, options); | ||||||
| @ -740,6 +748,7 @@ export class CoreCourseHelperProvider { | |||||||
|      * @param component The component to link the files to. |      * @param component The component to link the files to. | ||||||
|      * @param componentId An ID to use in conjunction with the component. |      * @param componentId An ID to use in conjunction with the component. | ||||||
|      * @param files List of files of the module. If not provided, use module.contents. |      * @param files List of files of the module. If not provided, use module.contents. | ||||||
|  |      * @param options Options to open the file. Only used if not opened in browser. | ||||||
|      * @return Resolved on success. |      * @return Resolved on success. | ||||||
|      */ |      */ | ||||||
|     protected async openModuleFileInBrowser( |     protected async openModuleFileInBrowser( | ||||||
| @ -750,6 +759,7 @@ export class CoreCourseHelperProvider { | |||||||
|         component?: string, |         component?: string, | ||||||
|         componentId?: string | number, |         componentId?: string | number, | ||||||
|         files?: CoreCourseModuleContentFile[], |         files?: CoreCourseModuleContentFile[], | ||||||
|  |         options: CoreUtilsOpenFileOptions = {}, | ||||||
|     ): Promise<void> { |     ): Promise<void> { | ||||||
|         if (!CoreApp.isOnline()) { |         if (!CoreApp.isOnline()) { | ||||||
|             // Not online, get the offline file. It will fail if not found.
 |             // Not online, get the offline file. It will fail if not found.
 | ||||||
| @ -760,7 +770,7 @@ export class CoreCourseHelperProvider { | |||||||
|                 throw new CoreNetworkError(); |                 throw new CoreNetworkError(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return CoreUtils.openFile(path); |             return CoreUtils.openFile(path, options); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Open in browser.
 |         // Open in browser.
 | ||||||
| @ -791,6 +801,7 @@ export class CoreCourseHelperProvider { | |||||||
|      * @param componentId An ID to use in conjunction with the component. |      * @param componentId An ID to use in conjunction with the component. | ||||||
|      * @param files List of files of the module. If not provided, use module.contents. |      * @param files List of files of the module. If not provided, use module.contents. | ||||||
|      * @param siteId The site ID. If not defined, current site. |      * @param siteId The site ID. If not defined, current site. | ||||||
|  |      * @param options Options to open the file. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     async downloadModuleWithMainFileIfNeeded( |     async downloadModuleWithMainFileIfNeeded( | ||||||
| @ -800,6 +811,7 @@ export class CoreCourseHelperProvider { | |||||||
|         componentId?: string | number, |         componentId?: string | number, | ||||||
|         files?: CoreCourseModuleContentFile[], |         files?: CoreCourseModuleContentFile[], | ||||||
|         siteId?: string, |         siteId?: string, | ||||||
|  |         options: CoreUtilsOpenFileOptions = {}, | ||||||
|     ): Promise<{ fixedUrl: string; path: string; status?: string }> { |     ): Promise<{ fixedUrl: string; path: string; status?: string }> { | ||||||
| 
 | 
 | ||||||
|         siteId = siteId || CoreSites.getCurrentSiteId(); |         siteId = siteId || CoreSites.getCurrentSiteId(); | ||||||
| @ -840,7 +852,17 @@ export class CoreCourseHelperProvider { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!path) { |         if (!path) { | ||||||
|             path = await this.downloadModuleWithMainFile(module, courseId, fixedUrl, files, status, component, componentId, siteId); |             path = await this.downloadModuleWithMainFile( | ||||||
|  |                 module, | ||||||
|  |                 courseId, | ||||||
|  |                 fixedUrl, | ||||||
|  |                 files, | ||||||
|  |                 status, | ||||||
|  |                 component, | ||||||
|  |                 componentId, | ||||||
|  |                 siteId, | ||||||
|  |                 options, | ||||||
|  |             ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return { |         return { | ||||||
| @ -862,6 +884,7 @@ export class CoreCourseHelperProvider { | |||||||
|      * @param component The component to link the files to. |      * @param component The component to link the files to. | ||||||
|      * @param componentId An ID to use in conjunction with the component. |      * @param componentId An ID to use in conjunction with the component. | ||||||
|      * @param siteId The site ID. If not defined, current site. |      * @param siteId The site ID. If not defined, current site. | ||||||
|  |      * @param options Options to open the file. | ||||||
|      * @return Promise resolved when done. |      * @return Promise resolved when done. | ||||||
|      */ |      */ | ||||||
|     protected async downloadModuleWithMainFile( |     protected async downloadModuleWithMainFile( | ||||||
| @ -873,6 +896,7 @@ export class CoreCourseHelperProvider { | |||||||
|         component?: string, |         component?: string, | ||||||
|         componentId?: string | number, |         componentId?: string | number, | ||||||
|         siteId?: string, |         siteId?: string, | ||||||
|  |         options: CoreUtilsOpenFileOptions = {}, | ||||||
|     ): Promise<string> { |     ): Promise<string> { | ||||||
|         siteId = siteId || CoreSites.getCurrentSiteId(); |         siteId = siteId || CoreSites.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
| @ -885,7 +909,7 @@ export class CoreCourseHelperProvider { | |||||||
|             throw new CoreNetworkError(); |             throw new CoreNetworkError(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const shouldDownloadFirst = await CoreFilepool.shouldDownloadFileBeforeOpen(fixedUrl, mainFile.filesize); |         const shouldDownloadFirst = await CoreFilepool.shouldDownloadFileBeforeOpen(fixedUrl, mainFile.filesize, options); | ||||||
| 
 | 
 | ||||||
|         if (shouldDownloadFirst) { |         if (shouldDownloadFirst) { | ||||||
|             // Download and then return the local URL.
 |             // Download and then return the local URL.
 | ||||||
|  | |||||||
| @ -46,7 +46,7 @@ export class CoreSitePluginsMainMenuHomeHandler extends CoreSitePluginsBaseHandl | |||||||
|         return { |         return { | ||||||
|             title: this.title, |             title: this.title, | ||||||
|             class: this.handlerSchema.displaydata?.class, |             class: this.handlerSchema.displaydata?.class, | ||||||
|             page: `siteplugins/${this.plugin.component}/${this.handlerSchema.method}/0`, |             page: `siteplugins/homecontent/${this.plugin.component}/${this.handlerSchema.method}`, | ||||||
|             pageParams: { |             pageParams: { | ||||||
|                 title: this.title, |                 title: this.title, | ||||||
|                 initResult: this.initResult, |                 initResult: this.initResult, | ||||||
|  | |||||||
| @ -28,6 +28,13 @@ const routes: Routes = [ | |||||||
|     }, |     }, | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
|  | const homeRoutes: Routes = [ | ||||||
|  |     { | ||||||
|  |         path: 'siteplugins/homecontent/:component/:method', | ||||||
|  |         loadChildren: () => import('./pages/plugin-page/plugin-page.module').then( m => m.CoreSitePluginsPluginPageModule), | ||||||
|  |     }, | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
| const courseIndexRoutes: Routes = [ | const courseIndexRoutes: Routes = [ | ||||||
|     { |     { | ||||||
|         path: 'siteplugins/:handlerUniqueName', |         path: 'siteplugins/:handlerUniqueName', | ||||||
| @ -47,7 +54,7 @@ const moduleRoutes: Routes = [ | |||||||
|     imports: [ |     imports: [ | ||||||
|         CoreMainMenuTabRoutingModule.forChild(moduleRoutes.concat(routes)), |         CoreMainMenuTabRoutingModule.forChild(moduleRoutes.concat(routes)), | ||||||
|         CoreCourseIndexRoutingModule.forChild({ children: courseIndexRoutes }), |         CoreCourseIndexRoutingModule.forChild({ children: courseIndexRoutes }), | ||||||
|         CoreMainMenuHomeRoutingModule.forChild({ children: routes }), |         CoreMainMenuHomeRoutingModule.forChild({ children: homeRoutes }), | ||||||
|         CoreSitePluginsComponentsModule, |         CoreSitePluginsComponentsModule, | ||||||
|     ], |     ], | ||||||
|     providers: [ |     providers: [ | ||||||
|  | |||||||
| @ -225,6 +225,7 @@ | |||||||
|     "percentagenumber": "{{$a}}%", |     "percentagenumber": "{{$a}}%", | ||||||
|     "phone": "Phone", |     "phone": "Phone", | ||||||
|     "pictureof": "Picture of {{$a}}", |     "pictureof": "Picture of {{$a}}", | ||||||
|  |     "play": "Play", | ||||||
|     "previous": "Previous", |     "previous": "Previous", | ||||||
|     "proceed": "Proceed", |     "proceed": "Proceed", | ||||||
|     "pulltorefresh": "Pull to refresh", |     "pulltorefresh": "Pull to refresh", | ||||||
|  | |||||||
| @ -73,7 +73,17 @@ export class CoreFileHelperProvider { | |||||||
|             await this.showConfirmOpenUnsupportedFile(); |             await this.showConfirmOpenUnsupportedFile(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         let url = await this.downloadFileIfNeeded(file, fileUrl, component, componentId, timemodified, state, onProgress, siteId); |         let url = await this.downloadFileIfNeeded( | ||||||
|  |             file, | ||||||
|  |             fileUrl, | ||||||
|  |             component, | ||||||
|  |             componentId, | ||||||
|  |             timemodified, | ||||||
|  |             state, | ||||||
|  |             onProgress, | ||||||
|  |             siteId, | ||||||
|  |             options, | ||||||
|  |         ); | ||||||
| 
 | 
 | ||||||
|         if (!url) { |         if (!url) { | ||||||
|             return; |             return; | ||||||
| @ -127,6 +137,7 @@ export class CoreFileHelperProvider { | |||||||
|      * @param state The file's state. If not provided, it will be calculated. |      * @param state The file's state. If not provided, it will be calculated. | ||||||
|      * @param onProgress Function to call on progress. |      * @param onProgress Function to call on progress. | ||||||
|      * @param siteId The site ID. If not defined, current site. |      * @param siteId The site ID. If not defined, current site. | ||||||
|  |      * @param options Options to open the file. | ||||||
|      * @return Resolved with the URL to use on success. |      * @return Resolved with the URL to use on success. | ||||||
|      */ |      */ | ||||||
|     protected async downloadFileIfNeeded( |     protected async downloadFileIfNeeded( | ||||||
| @ -138,6 +149,7 @@ export class CoreFileHelperProvider { | |||||||
|         state?: string, |         state?: string, | ||||||
|         onProgress?: CoreFileHelperOnProgress, |         onProgress?: CoreFileHelperOnProgress, | ||||||
|         siteId?: string, |         siteId?: string, | ||||||
|  |         options: CoreUtilsOpenFileOptions = {}, | ||||||
|     ): Promise<string> { |     ): Promise<string> { | ||||||
|         siteId = siteId || CoreSites.getCurrentSiteId(); |         siteId = siteId || CoreSites.getCurrentSiteId(); | ||||||
| 
 | 
 | ||||||
| @ -172,7 +184,7 @@ export class CoreFileHelperProvider { | |||||||
|                 onProgress({ calculating: true }); |                 onProgress({ calculating: true }); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             const shouldDownloadFirst = await CoreFilepool.shouldDownloadFileBeforeOpen(fixedUrl, file.filesize || 0); |             const shouldDownloadFirst = await CoreFilepool.shouldDownloadFileBeforeOpen(fixedUrl, file.filesize || 0, options); | ||||||
|             if (shouldDownloadFirst) { |             if (shouldDownloadFirst) { | ||||||
|                 // Download the file first.
 |                 // Download the file first.
 | ||||||
|                 if (state == CoreConstants.DOWNLOADING) { |                 if (state == CoreConstants.DOWNLOADING) { | ||||||
|  | |||||||
| @ -26,7 +26,7 @@ import { CoreMimetypeUtils } from '@services/utils/mimetype'; | |||||||
| import { CoreTextUtils } from '@services/utils/text'; | import { CoreTextUtils } from '@services/utils/text'; | ||||||
| import { CoreTimeUtils } from '@services/utils/time'; | import { CoreTimeUtils } from '@services/utils/time'; | ||||||
| import { CoreUrlUtils } from '@services/utils/url'; | import { CoreUrlUtils } from '@services/utils/url'; | ||||||
| import { CoreUtils, PromiseDefer } from '@services/utils/utils'; | import { CoreUtils, CoreUtilsOpenFileOptions, PromiseDefer } from '@services/utils/utils'; | ||||||
| import { SQLiteDB } from '@classes/sqlitedb'; | import { SQLiteDB } from '@classes/sqlitedb'; | ||||||
| import { CoreError } from '@classes/errors/error'; | import { CoreError } from '@classes/errors/error'; | ||||||
| import { CoreConstants } from '@/core/constants'; | import { CoreConstants } from '@/core/constants'; | ||||||
| @ -2781,7 +2781,7 @@ export class CoreFilepoolProvider { | |||||||
| 
 | 
 | ||||||
|         const mimetype = await CoreUtils.getMimeTypeFromUrl(url); |         const mimetype = await CoreUtils.getMimeTypeFromUrl(url); | ||||||
|         // If the file is streaming (audio or video) we reject.
 |         // If the file is streaming (audio or video) we reject.
 | ||||||
|         if (mimetype.indexOf('video') != -1 || mimetype.indexOf('audio') != -1) { |         if (CoreMimetypeUtils.isStreamedMimetype(mimetype)) { | ||||||
|             throw new CoreError('File is audio or video.'); |             throw new CoreError('File is audio or video.'); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -2791,6 +2791,7 @@ export class CoreFilepoolProvider { | |||||||
|      * |      * | ||||||
|      * @param url File online URL. |      * @param url File online URL. | ||||||
|      * @param size File size. |      * @param size File size. | ||||||
|  |      * @param options Options. | ||||||
|      * @return Promise resolved with boolean: whether file should be downloaded before opening it. |      * @return Promise resolved with boolean: whether file should be downloaded before opening it. | ||||||
|      * @description |      * @description | ||||||
|      * Convenience function to check if a file should be downloaded before opening it. |      * Convenience function to check if a file should be downloaded before opening it. | ||||||
| @ -2800,16 +2801,21 @@ export class CoreFilepoolProvider { | |||||||
|      *     - The file cannot be streamed. |      *     - The file cannot be streamed. | ||||||
|      * If the file is big and can be streamed, the promise returned by this function will be rejected. |      * If the file is big and can be streamed, the promise returned by this function will be rejected. | ||||||
|      */ |      */ | ||||||
|     async shouldDownloadFileBeforeOpen(url: string, size: number): Promise<boolean> { |     async shouldDownloadFileBeforeOpen(url: string, size: number, options: CoreUtilsOpenFileOptions = {}): Promise<boolean> { | ||||||
|         if (size >= 0 && size <= CoreFilepoolProvider.DOWNLOAD_THRESHOLD) { |         if (size >= 0 && size <= CoreFilepoolProvider.DOWNLOAD_THRESHOLD) { | ||||||
|             // The file is small, download it.
 |             // The file is small, download it.
 | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (CoreUtils.shouldOpenWithDialog(options)) { | ||||||
|  |             // Open with dialog needs a local file.
 | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         const mimetype = await CoreUtils.getMimeTypeFromUrl(url); |         const mimetype = await CoreUtils.getMimeTypeFromUrl(url); | ||||||
| 
 | 
 | ||||||
|         // If the file is streaming (audio or video), return false.
 |         // If the file is streaming (audio or video), return false.
 | ||||||
|         return mimetype.indexOf('video') == -1 && mimetype.indexOf('audio') == -1; |         return !CoreMimetypeUtils.isStreamedMimetype(mimetype); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -562,6 +562,16 @@ export class CoreMimetypeUtilsProvider { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if a mimetype belongs to a file that can be streamed (audio, video). | ||||||
|  |      * | ||||||
|  |      * @param mimetype Mimetype. | ||||||
|  |      * @return Boolean. | ||||||
|  |      */ | ||||||
|  |     isStreamedMimetype(mimetype: string): boolean { | ||||||
|  |         return mimetype.indexOf('video') != -1 || mimetype.indexOf('audio') != -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Remove the extension from a path (if any). |      * Remove the extension from a path (if any). | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -933,8 +933,7 @@ export class CoreUtilsProvider { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             const openFileAction = options.iOSOpenFileAction ?? CoreConstants.CONFIG.iOSDefaultOpenFileAction; |             if (this.shouldOpenWithDialog(options)) { | ||||||
|             if (CoreApp.isIOS() && openFileAction == OpenFileAction.OPEN_WITH) { |  | ||||||
|                 await FileOpener.showOpenWithDialog(path, mimetype || ''); |                 await FileOpener.showOpenWithDialog(path, mimetype || ''); | ||||||
|             } else { |             } else { | ||||||
|                 await FileOpener.open(path, mimetype || ''); |                 await FileOpener.open(path, mimetype || ''); | ||||||
| @ -1652,6 +1651,18 @@ export class CoreUtilsProvider { | |||||||
|         return this.wait(0); |         return this.wait(0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Given some options, check if a file should be opened with showOpenWithDialog. | ||||||
|  |      * | ||||||
|  |      * @param options Options. | ||||||
|  |      * @return Boolean. | ||||||
|  |      */ | ||||||
|  |     shouldOpenWithDialog(options: CoreUtilsOpenFileOptions = {}): boolean { | ||||||
|  |         const openFileAction = options.iOSOpenFileAction ?? CoreConstants.CONFIG.iOSDefaultOpenFileAction; | ||||||
|  | 
 | ||||||
|  |         return CoreApp.isIOS() && openFileAction == OpenFileAction.OPEN_WITH; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const CoreUtils = makeSingleton(CoreUtilsProvider); | export const CoreUtils = makeSingleton(CoreUtilsProvider); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user