MOBILE-3320 resource: Fix 'Open with' with streaming and external repos
parent
9dfe556066
commit
edf5763809
|
@ -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",
|
||||||
|
|
|
@ -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)">
|
||||||
<ion-icon name="far-file" slot="start" aria-hidden="true"></ion-icon>
|
<ng-container *ngIf="isStreamedFile">
|
||||||
{{ 'addon.mod_resource.openthefile' | translate }}
|
<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>
|
||||||
|
{{ '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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -691,11 +691,19 @@ export class CoreCourseHelperProvider {
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
|
@ -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…
Reference in New Issue