MOBILE-3565 components: Create core-file component
@ -17,6 +17,8 @@ import { CommonModule } from '@angular/common';
 | 
			
		||||
import { IonicModule } from '@ionic/angular';
 | 
			
		||||
import { TranslateModule } from '@ngx-translate/core';
 | 
			
		||||
 | 
			
		||||
import { CoreDownloadRefreshComponent } from './download-refresh/download-refresh';
 | 
			
		||||
import { CoreFileComponent } from './file/file';
 | 
			
		||||
import { CoreIconComponent } from './icon/icon';
 | 
			
		||||
import { CoreIframeComponent } from './iframe/iframe';
 | 
			
		||||
import { CoreInputErrorsComponent } from './input-errors/input-errors';
 | 
			
		||||
@ -31,6 +33,8 @@ import { CorePipesModule } from '@app/pipes/pipes.module';
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    declarations: [
 | 
			
		||||
        CoreDownloadRefreshComponent,
 | 
			
		||||
        CoreFileComponent,
 | 
			
		||||
        CoreIconComponent,
 | 
			
		||||
        CoreIframeComponent,
 | 
			
		||||
        CoreInputErrorsComponent,
 | 
			
		||||
@ -49,6 +53,8 @@ import { CorePipesModule } from '@app/pipes/pipes.module';
 | 
			
		||||
        CorePipesModule,
 | 
			
		||||
    ],
 | 
			
		||||
    exports: [
 | 
			
		||||
        CoreDownloadRefreshComponent,
 | 
			
		||||
        CoreFileComponent,
 | 
			
		||||
        CoreIconComponent,
 | 
			
		||||
        CoreIframeComponent,
 | 
			
		||||
        CoreInputErrorsComponent,
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,20 @@
 | 
			
		||||
<ng-container *ngIf="enabled && !(loading || status === statusDownloading)">
 | 
			
		||||
    <!-- Download button. -->
 | 
			
		||||
    <ion-button *ngIf="status == statusNotDownloaded" fill="clear" (click)="download($event, false)" color="dark"
 | 
			
		||||
        class="core-animate-show-hide" [attr.aria-label]="'core.download' | translate">
 | 
			
		||||
        <ion-icon slot="icon-only" name="cloud-download"></ion-icon>
 | 
			
		||||
    </ion-button>
 | 
			
		||||
 | 
			
		||||
    <!-- Refresh button. -->
 | 
			
		||||
    <ion-button *ngIf="status == statusOutdated || (status == statusDownloaded && !canTrustDownload)" fill="clear"
 | 
			
		||||
        (click)="download($event, true)" color="dark" class="core-animate-show-hide" [attr.aria-label]="'core.refresh' | translate">
 | 
			
		||||
        <ion-icon slot="icon-only" name="fas-sync"></ion-icon>
 | 
			
		||||
    </ion-button>
 | 
			
		||||
 | 
			
		||||
    <!-- Downloaded status icon. -->
 | 
			
		||||
    <ion-icon *ngIf="status == statusDownloaded && canTrustDownload" class="core-icon-downloaded ion-padding-horizontal" color="success"
 | 
			
		||||
        name="cloud-done" [attr.aria-label]="'core.downloaded' | translate" role="status"></ion-icon>
 | 
			
		||||
</ng-container>
 | 
			
		||||
 | 
			
		||||
<!-- Spinner. -->
 | 
			
		||||
<ion-spinner *ngIf="loading || status === statusDownloading" class="core-animate-show-hide"></ion-spinner>
 | 
			
		||||
@ -0,0 +1,8 @@
 | 
			
		||||
:host {
 | 
			
		||||
    font-size: 1.4rem;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-flow: row;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    justify-content: space-around;
 | 
			
		||||
    align-content: center;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								src/app/components/download-refresh/download-refresh.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,59 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
 | 
			
		||||
import { CoreConstants } from '@core/constants';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to show a download button with refresh option, the spinner and the status of it.
 | 
			
		||||
 *
 | 
			
		||||
 * Usage:
 | 
			
		||||
 * <core-download-refresh [status]="status" enabled="true" canCheckUpdates="true" action="download()"></core-download-refresh>
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'core-download-refresh',
 | 
			
		||||
    templateUrl: 'core-download-refresh.html',
 | 
			
		||||
    styleUrls: ['download-refresh.scss'],
 | 
			
		||||
})
 | 
			
		||||
export class CoreDownloadRefreshComponent {
 | 
			
		||||
 | 
			
		||||
    @Input() status?: string; // Download status.
 | 
			
		||||
    @Input() enabled = false; // Whether the download is enabled.
 | 
			
		||||
    @Input() loading = true; // Force loading status when is not downloading.
 | 
			
		||||
    @Input() canTrustDownload = false; // If false, refresh will be shown if downloaded.
 | 
			
		||||
    @Output() action: EventEmitter<boolean>; // Will emit an event when the item clicked.
 | 
			
		||||
 | 
			
		||||
    statusDownloaded = CoreConstants.DOWNLOADED;
 | 
			
		||||
    statusNotDownloaded = CoreConstants.NOT_DOWNLOADED;
 | 
			
		||||
    statusOutdated = CoreConstants.OUTDATED;
 | 
			
		||||
    statusDownloading = CoreConstants.DOWNLOADING;
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.action = new EventEmitter();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Download clicked.
 | 
			
		||||
     *
 | 
			
		||||
     * @param e Click event.
 | 
			
		||||
     * @param refresh Whether it's refreshing.
 | 
			
		||||
     */
 | 
			
		||||
    download(e: Event, refresh: boolean): void {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        this.action.emit(refresh);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/app/components/file/core-file.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,20 @@
 | 
			
		||||
<ion-item *ngIf="file" button class="ion-text-wrap item-media" (click)="download($event, true)" detail="false">
 | 
			
		||||
    <ion-thumbnail slot="start">
 | 
			
		||||
        <img [src]="fileIcon" alt="" role="presentation" />
 | 
			
		||||
    </ion-thumbnail>
 | 
			
		||||
    <ion-label>
 | 
			
		||||
        <h2>{{fileName}}</h2>
 | 
			
		||||
        <p *ngIf="fileSizeReadable">{{ fileSizeReadable }}</p>
 | 
			
		||||
        <p *ngIf="showTime">{{ timemodified * 1000 | coreFormatDate }}</p>
 | 
			
		||||
    </ion-label>
 | 
			
		||||
    <div slot="end">
 | 
			
		||||
        <core-download-refresh [status]="state" [enabled]="canDownload" [loading]="isDownloading"
 | 
			
		||||
            [canTrustDownload]="!alwaysDownload" (action)="download()">
 | 
			
		||||
        </core-download-refresh>
 | 
			
		||||
 | 
			
		||||
        <ion-button fill="clear" *ngIf="!isDownloading && canDelete" (click)="delete($event)"
 | 
			
		||||
            [attr.aria-label]="'core.delete' | translate" color="danger">
 | 
			
		||||
            <ion-icon slot="icon-only" name="fas-trash"></ion-icon>
 | 
			
		||||
        </ion-button>
 | 
			
		||||
    </div>
 | 
			
		||||
</ion-item>
 | 
			
		||||
							
								
								
									
										31
									
								
								src/app/components/file/file.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,31 @@
 | 
			
		||||
:host {
 | 
			
		||||
    // @todo
 | 
			
		||||
    // .card-md core-file + core-file > .item-md.item-block > .item-inner,
 | 
			
		||||
    // core-file + core-file > .item-md.item-block > .item-inner {
 | 
			
		||||
    //     border-top: 1px solid $list-md-border-color;
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // .card-ios core-file + core-file > .item-ios.item-block > .item-inner,
 | 
			
		||||
    // core-file + core-file > .item-ios.item-block > .item-inner {
 | 
			
		||||
    //     border-top: $hairlines-width solid $list-ios-border-color;
 | 
			
		||||
    //     .buttons {
 | 
			
		||||
    //         min-height: 53px;
 | 
			
		||||
    //         min-width: 58px;
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // core-file > .item.item-block > .item-inner {
 | 
			
		||||
    //     border-bottom: 0;
 | 
			
		||||
    //     @include safe-area-padding(null, 0px, null, null);
 | 
			
		||||
    //     .buttons {
 | 
			
		||||
    //         display: flex;
 | 
			
		||||
    //         flex-flow: row;
 | 
			
		||||
    //         align-items: center;
 | 
			
		||||
    //         z-index: 1;
 | 
			
		||||
    //         justify-content: space-around;
 | 
			
		||||
    //         align-content: center;
 | 
			
		||||
    //         min-height: 52px;
 | 
			
		||||
    //         min-width: 53px;
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										253
									
								
								src/app/components/file/file.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,253 @@
 | 
			
		||||
// (C) Copyright 2015 Moodle Pty Ltd.
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
import { Component, Input, Output, OnInit, OnDestroy, EventEmitter } from '@angular/core';
 | 
			
		||||
import { CoreApp } from '@services/app';
 | 
			
		||||
import { CoreFilepool } from '@services/filepool';
 | 
			
		||||
import { CoreFileHelper } from '@services/file-helper';
 | 
			
		||||
import { CorePluginFileDelegate } from '@services/plugin-file-delegate';
 | 
			
		||||
import { CoreSites } from '@services/sites';
 | 
			
		||||
import { CoreDomUtils } from '@services/utils/dom';
 | 
			
		||||
import { CoreMimetypeUtils } from '@services/utils/mimetype';
 | 
			
		||||
import { CoreUrlUtils } from '@services/utils/url';
 | 
			
		||||
import { CoreUtils } from '@services/utils/utils';
 | 
			
		||||
import { CoreTextUtils } from '@services/utils/text';
 | 
			
		||||
import { CoreConstants } from '@core/constants';
 | 
			
		||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
 | 
			
		||||
import { CoreWSExternalFile } from '@/app/services/ws';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to handle a remote file. Shows the file name, icon (depending on mimetype) and a button
 | 
			
		||||
 * to download/refresh it.
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'core-file',
 | 
			
		||||
    templateUrl: 'core-file.html',
 | 
			
		||||
    styleUrls: ['file.scss'],
 | 
			
		||||
})
 | 
			
		||||
export class CoreFileComponent implements OnInit, OnDestroy {
 | 
			
		||||
 | 
			
		||||
    @Input() file?: CoreWSExternalFile; // The file.
 | 
			
		||||
    @Input() component?: string; // Component the file belongs to.
 | 
			
		||||
    @Input() componentId?: string | number; // Component ID.
 | 
			
		||||
    @Input() canDelete?: boolean | string; // Whether file can be deleted.
 | 
			
		||||
    @Input() alwaysDownload?: boolean | string; // Whether it should always display the refresh button when the file is downloaded.
 | 
			
		||||
    @Input() canDownload?: boolean | string = true; // Whether file can be downloaded.
 | 
			
		||||
    @Input() showSize?: boolean | string = true; // Whether show filesize.
 | 
			
		||||
    @Input() showTime?: boolean | string = true; // Whether show file time modified.
 | 
			
		||||
    @Output() onDelete: EventEmitter<void>; // Will notify when the delete button is clicked.
 | 
			
		||||
 | 
			
		||||
    isDownloading?: boolean;
 | 
			
		||||
    fileIcon?: string;
 | 
			
		||||
    fileName!: string;
 | 
			
		||||
    fileSizeReadable?: string;
 | 
			
		||||
    state?: string;
 | 
			
		||||
    timemodified!: number;
 | 
			
		||||
 | 
			
		||||
    protected fileUrl!: string;
 | 
			
		||||
    protected siteId?: string;
 | 
			
		||||
    protected fileSize?: number;
 | 
			
		||||
    protected observer?: CoreEventObserver;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        protected pluginFileDelegate: CorePluginFileDelegate,
 | 
			
		||||
    ) {
 | 
			
		||||
        this.onDelete = new EventEmitter<void>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Component being initialized.
 | 
			
		||||
     */
 | 
			
		||||
    async ngOnInit(): Promise<void> {
 | 
			
		||||
        if (!this.file) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.canDelete = CoreUtils.instance.isTrueOrOne(this.canDelete);
 | 
			
		||||
        this.alwaysDownload = CoreUtils.instance.isTrueOrOne(this.alwaysDownload);
 | 
			
		||||
        this.canDownload = CoreUtils.instance.isTrueOrOne(this.canDownload);
 | 
			
		||||
 | 
			
		||||
        this.fileUrl = this.file.fileurl;
 | 
			
		||||
        this.timemodified = this.file.timemodified || 0;
 | 
			
		||||
        this.siteId = CoreSites.instance.getCurrentSiteId();
 | 
			
		||||
        this.fileSize = this.file.filesize;
 | 
			
		||||
        this.fileName = this.file.filename || '';
 | 
			
		||||
 | 
			
		||||
        if (CoreUtils.instance.isTrueOrOne(this.showSize) && this.fileSize && this.fileSize >= 0) {
 | 
			
		||||
            this.fileSizeReadable = CoreTextUtils.instance.bytesToSize(this.fileSize, 2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.showTime = CoreUtils.instance.isTrueOrOne(this.showTime) && this.timemodified > 0;
 | 
			
		||||
 | 
			
		||||
        if (this.file.isexternalfile) {
 | 
			
		||||
            this.alwaysDownload = true; // Always show the download button in external files.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.fileIcon = this.file.mimetype ? CoreMimetypeUtils.instance.getMimetypeIcon(this.file.mimetype) :
 | 
			
		||||
            CoreMimetypeUtils.instance.getFileIcon(this.fileName);
 | 
			
		||||
 | 
			
		||||
        if (this.canDownload) {
 | 
			
		||||
            this.calculateState();
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                // Update state when receiving events about this file.
 | 
			
		||||
                const eventName = await CoreFilepool.instance.getFileEventNameByUrl(this.siteId, this.fileUrl);
 | 
			
		||||
 | 
			
		||||
                this.observer = CoreEvents.on(eventName, () => {
 | 
			
		||||
                    this.calculateState();
 | 
			
		||||
                });
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
                // File not downloadable.
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convenience function to get the file state and set variables based on it.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Promise resolved when state has been calculated.
 | 
			
		||||
     */
 | 
			
		||||
    protected async calculateState(): Promise<void> {
 | 
			
		||||
        if (!this.siteId) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const state = await CoreFilepool.instance.getFileStateByUrl(this.siteId, this.fileUrl, this.timemodified);
 | 
			
		||||
 | 
			
		||||
        const site = await CoreSites.instance.getSite(this.siteId);
 | 
			
		||||
 | 
			
		||||
        this.canDownload = site.canDownloadFiles();
 | 
			
		||||
 | 
			
		||||
        this.state = state;
 | 
			
		||||
        this.isDownloading = this.canDownload && state === CoreConstants.DOWNLOADING;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Convenience function to open a file, downloading it if needed.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Promise resolved when file is opened.
 | 
			
		||||
     */
 | 
			
		||||
    protected openFile(): Promise<void> {
 | 
			
		||||
        return CoreFileHelper.instance.downloadAndOpenFile(this.file!, this.component, this.componentId, this.state, (event) => {
 | 
			
		||||
            if (event && 'calculating' in event && event.calculating) {
 | 
			
		||||
                // The process is calculating some data required for the download, show the spinner.
 | 
			
		||||
                this.isDownloading = true;
 | 
			
		||||
            }
 | 
			
		||||
        }).catch((error) => {
 | 
			
		||||
            CoreDomUtils.instance.showErrorModalDefault(error, 'core.errordownloading', true);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Download a file and, optionally, open it afterwards.
 | 
			
		||||
     *
 | 
			
		||||
     * @param e Click event.
 | 
			
		||||
     * @param openAfterDownload Whether the file should be opened after download.
 | 
			
		||||
     */
 | 
			
		||||
    async download(e?: Event, openAfterDownload: boolean = false): Promise<void> {
 | 
			
		||||
        e && e.preventDefault();
 | 
			
		||||
        e && e.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        if (!this.file || !this.siteId) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.isDownloading && !openAfterDownload) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!this.canDownload || !this.state || this.state == CoreConstants.NOT_DOWNLOADABLE) {
 | 
			
		||||
            // File cannot be downloaded, just open it.
 | 
			
		||||
            if (CoreUrlUtils.instance.isLocalFileUrl(this.fileUrl)) {
 | 
			
		||||
                CoreUtils.instance.openFile(this.fileUrl);
 | 
			
		||||
            } else {
 | 
			
		||||
                CoreUtils.instance.openOnlineFile(CoreUrlUtils.instance.unfixPluginfileURL(this.fileUrl));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!CoreApp.instance.isOnline() && (!openAfterDownload || (openAfterDownload &&
 | 
			
		||||
                !CoreFileHelper.instance.isStateDownloaded(this.state)))) {
 | 
			
		||||
            CoreDomUtils.instance.showErrorModal('core.networkerrormsg', true);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (openAfterDownload) {
 | 
			
		||||
            // File needs to be opened now.
 | 
			
		||||
            try {
 | 
			
		||||
                await this.openFile();
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
                CoreDomUtils.instance.showErrorModalDefault(error, 'core.errordownloading', true);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            try {
 | 
			
		||||
                // File doesn't need to be opened (it's a prefetch). Show confirm modal if file size is defined and it's big.
 | 
			
		||||
                const size = await this.pluginFileDelegate.getFileSize(this.file, this.siteId);
 | 
			
		||||
 | 
			
		||||
                if (size) {
 | 
			
		||||
                    await CoreDomUtils.instance.confirmDownloadSize({ size: size, total: true });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // User confirmed, add the file to queue.
 | 
			
		||||
                // @todo: Is the invalidate really needed?
 | 
			
		||||
                await CoreUtils.instance.ignoreErrors(CoreFilepool.instance.invalidateFileByUrl(this.siteId, this.fileUrl));
 | 
			
		||||
 | 
			
		||||
                this.isDownloading = true;
 | 
			
		||||
 | 
			
		||||
                try {
 | 
			
		||||
                    await CoreFilepool.instance.addToQueueByUrl(
 | 
			
		||||
                        this.siteId,
 | 
			
		||||
                        this.fileUrl,
 | 
			
		||||
                        this.component,
 | 
			
		||||
                        this.componentId,
 | 
			
		||||
                        this.timemodified,
 | 
			
		||||
                        undefined,
 | 
			
		||||
                        undefined,
 | 
			
		||||
                        0,
 | 
			
		||||
                        this.file,
 | 
			
		||||
                    );
 | 
			
		||||
                } catch (error) {
 | 
			
		||||
                    CoreDomUtils.instance.showErrorModalDefault(error, 'core.errordownloading', true);
 | 
			
		||||
                    this.calculateState();
 | 
			
		||||
                }
 | 
			
		||||
            } catch (error) {
 | 
			
		||||
                CoreDomUtils.instance.showErrorModalDefault(error, 'core.errordownloading', true);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete the file.
 | 
			
		||||
     *
 | 
			
		||||
     * @param e Click event.
 | 
			
		||||
     */
 | 
			
		||||
    delete(e: Event): void {
 | 
			
		||||
        e.preventDefault();
 | 
			
		||||
        e.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        if (this.canDelete) {
 | 
			
		||||
            this.onDelete.emit();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Component destroyed.
 | 
			
		||||
     */
 | 
			
		||||
    ngOnDestroy(): void {
 | 
			
		||||
        this.observer?.off();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -46,8 +46,8 @@ export class CoreFileHelperProvider {
 | 
			
		||||
     */
 | 
			
		||||
    async downloadAndOpenFile(
 | 
			
		||||
        file: CoreWSExternalFile,
 | 
			
		||||
        component: string,
 | 
			
		||||
        componentId: string | number,
 | 
			
		||||
        component?: string,
 | 
			
		||||
        componentId?: string | number,
 | 
			
		||||
        state?: string,
 | 
			
		||||
        onProgress?: CoreFileHelperOnProgress,
 | 
			
		||||
        siteId?: string,
 | 
			
		||||
 | 
			
		||||
@ -251,7 +251,7 @@ export class CoreFileProvider {
 | 
			
		||||
     * @return Promise to be resolved when the file is created.
 | 
			
		||||
     */
 | 
			
		||||
    async createFile(path: string, failIfExists?: boolean): Promise<FileEntry> {
 | 
			
		||||
        const entry = <FileEntry> await this.create(true, path, failIfExists);
 | 
			
		||||
        const entry = <FileEntry> await this.create(false, path, failIfExists);
 | 
			
		||||
 | 
			
		||||
        return entry;
 | 
			
		||||
    }
 | 
			
		||||
@ -568,8 +568,7 @@ export class CoreFileProvider {
 | 
			
		||||
        // Create file (and parent folders) to prevent errors.
 | 
			
		||||
        const fileEntry = await this.createFile(path);
 | 
			
		||||
 | 
			
		||||
        if (this.isHTMLAPI &&
 | 
			
		||||
                (typeof data == 'string' || data.toString() == '[object ArrayBuffer]')) {
 | 
			
		||||
        if (this.isHTMLAPI && (typeof data == 'string' || data.toString() == '[object ArrayBuffer]')) {
 | 
			
		||||
            // We need to write Blobs.
 | 
			
		||||
            const extension = CoreMimetypeUtils.instance.getFileExtension(path);
 | 
			
		||||
            const type = extension ? CoreMimetypeUtils.instance.getMimeType(extension) : '';
 | 
			
		||||
 | 
			
		||||
@ -17,11 +17,14 @@ import { FileEntry } from '@ionic-native/file';
 | 
			
		||||
 | 
			
		||||
import { CoreFile } from '@services/file';
 | 
			
		||||
import { CoreTextUtils } from '@services/utils/text';
 | 
			
		||||
import { makeSingleton, Translate, Http } from '@singletons/core.singletons';
 | 
			
		||||
import { makeSingleton, Translate } from '@singletons/core.singletons';
 | 
			
		||||
import { CoreLogger } from '@singletons/logger';
 | 
			
		||||
import { CoreWSExternalFile } from '@services/ws';
 | 
			
		||||
import { CoreUtils } from '@services/utils/utils';
 | 
			
		||||
 | 
			
		||||
import extToMime from '@/assets/exttomime.json';
 | 
			
		||||
import mimeToExt from '@/assets/mimetoext.json';
 | 
			
		||||
 | 
			
		||||
interface MimeTypeInfo {
 | 
			
		||||
    type: string;
 | 
			
		||||
    icon?: string;
 | 
			
		||||
@ -52,17 +55,8 @@ export class CoreMimetypeUtilsProvider {
 | 
			
		||||
    constructor() {
 | 
			
		||||
        this.logger = CoreLogger.getInstance('CoreMimetypeUtilsProvider');
 | 
			
		||||
 | 
			
		||||
        Http.instance.get('assets/exttomime.json').subscribe((result: Record<string, MimeTypeInfo>) => {
 | 
			
		||||
            this.extToMime = result;
 | 
			
		||||
        }, () => {
 | 
			
		||||
            // Error, shouldn't happen.
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Http.instance.get('assets/mimetoext.json').subscribe((result: Record<string, string[]>) => {
 | 
			
		||||
            this.mimeToExt = result;
 | 
			
		||||
        }, () => {
 | 
			
		||||
            // Error, shouldn't happen
 | 
			
		||||
        });
 | 
			
		||||
        this.extToMime = extToMime;
 | 
			
		||||
        this.mimeToExt = mimeToExt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/archive-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/audio-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/avi-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/base-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/bmp-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/calc-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/chart-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/database-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/document-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/draw-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/eps-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/epub-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/flash-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/folder-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/folder-open-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/gif-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/h5p-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/html-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/image-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/impress-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/isf-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/jpeg-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/markup-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/math-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/moodle-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/mp3-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/mpeg-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/oth-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/pdf-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/png-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/powerpoint-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/psd-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/publisher-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/quicktime-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/sourcecode-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/spreadsheet-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/text-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/tiff-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/unknown-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/video-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/wav-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/wmv-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/img/files/writer-64.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  |