forked from CIT/Vmeda.Online
		
	MOBILE-3205 forum: Show attachments as inline files
This commit is contained in:
		
							parent
							
								
									ccf4aeadea
								
							
						
					
					
						commit
						34ac2a93d8
					
				@ -2,13 +2,7 @@
 | 
			
		||||
<ion-item text-wrap *ngIf="files && files.length && !edit">
 | 
			
		||||
    <h2>{{plugin.name}}</h2>
 | 
			
		||||
    <div no-lines>
 | 
			
		||||
        <ng-container *ngFor="let file of files">
 | 
			
		||||
            <!-- Files already attached to the submission. -->
 | 
			
		||||
            <core-file *ngIf="!file.name" [file]="file" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-file>
 | 
			
		||||
 | 
			
		||||
            <!-- Files stored in offline to be sent later. -->
 | 
			
		||||
            <core-local-file *ngIf="file.name" [file]="file"></core-local-file>
 | 
			
		||||
        </ng-container>
 | 
			
		||||
        <core-files [files]="files" [component]="component" [componentId]="assign.cmid" [alwaysDownload]="true"></core-files>
 | 
			
		||||
    </div>
 | 
			
		||||
</ion-item>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,12 +10,6 @@
 | 
			
		||||
 | 
			
		||||
<ng-container *ngIf="isShowOrListMode()">
 | 
			
		||||
    <div no-lines>
 | 
			
		||||
        <ng-container *ngFor="let file of files">
 | 
			
		||||
            <!-- Files already attached to the submission. -->
 | 
			
		||||
            <core-file *ngIf="!file.name" [file]="file" [component]="component" [componentId]="componentId" [alwaysDownload]="true"></core-file>
 | 
			
		||||
 | 
			
		||||
            <!-- Files stored in offline to be sent later. -->
 | 
			
		||||
            <core-local-file *ngIf="file.name" [file]="file"></core-local-file>
 | 
			
		||||
        </ng-container>
 | 
			
		||||
        <core-files [files]="files" [component]="component" [componentId]="componentId" [alwaysDownload]="true"></core-files>
 | 
			
		||||
    </div>
 | 
			
		||||
</ng-container>
 | 
			
		||||
 | 
			
		||||
@ -27,12 +27,7 @@
 | 
			
		||||
    </div>
 | 
			
		||||
    <core-format-text [component]="component" [componentId]="componentId" [text]="post.message" contextLevel="module" [contextInstanceId]="forum && forum.cmid" [courseId]="courseId"></core-format-text>
 | 
			
		||||
    <div no-lines>
 | 
			
		||||
        <ng-container *ngFor="let attachment of post.attachments">
 | 
			
		||||
            <!-- Files already attached to the submission. -->
 | 
			
		||||
            <core-file *ngIf="!attachment.name" [file]="attachment" [component]="component" [componentId]="componentId"></core-file>
 | 
			
		||||
            <!-- Files stored in offline to be sent later. -->
 | 
			
		||||
            <core-local-file *ngIf="attachment.name" [file]="attachment"></core-local-file>
 | 
			
		||||
        </ng-container>
 | 
			
		||||
        <core-files *ngIf="post.attachments && post.attachments.length > 0" [files]="post.attachments" [component]="component" [componentId]="componentId" showInline="true"></core-files>
 | 
			
		||||
    </div>
 | 
			
		||||
</ion-card-content>
 | 
			
		||||
<div class="addon-mod-forum-post-more-info">
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
        <ion-card class="core-info-card" icon-start *ngIf="discussion && discussion.locked">
 | 
			
		||||
            <ion-icon name="information-circle"></ion-icon> {{ 'addon.mod_forum.discussionlocked' | translate }}
 | 
			
		||||
            <core-icon name="fa-lock"></core-icon> {{ 'addon.mod_forum.discussionlocked' | translate }}
 | 
			
		||||
        </ion-card>
 | 
			
		||||
 | 
			
		||||
        <ion-card *ngIf="discussion" margin-bottom class="highlight">
 | 
			
		||||
 | 
			
		||||
@ -134,6 +134,8 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
 | 
			
		||||
 | 
			
		||||
                return this.resourceHelper.getEmbeddedHtml(this.module, this.courseId).then((html) => {
 | 
			
		||||
                    this.contentText = html;
 | 
			
		||||
 | 
			
		||||
                    this.mode = this.contentText.length > 0 ? 'embedded' : 'external';
 | 
			
		||||
                });
 | 
			
		||||
            } else {
 | 
			
		||||
                this.mode = 'external';
 | 
			
		||||
 | 
			
		||||
@ -53,23 +53,7 @@ export class AddonModResourceHelperProvider {
 | 
			
		||||
    getEmbeddedHtml(module: any, courseId: number): Promise<any> {
 | 
			
		||||
        return this.courseHelper.downloadModuleWithMainFileIfNeeded(module, courseId, AddonModResourceProvider.COMPONENT,
 | 
			
		||||
                module.id, module.contents).then((result) => {
 | 
			
		||||
            const file = module.contents[0],
 | 
			
		||||
                ext = this.mimetypeUtils.getFileExtension(file.filename),
 | 
			
		||||
                type = this.mimetypeUtils.getExtensionType(ext),
 | 
			
		||||
                mimeType = this.mimetypeUtils.getMimeType(ext);
 | 
			
		||||
 | 
			
		||||
            if (type == 'image') {
 | 
			
		||||
                return '<img src="' + result.path + '"></img>';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (type == 'audio' || type == 'video') {
 | 
			
		||||
                return '<' + type + ' controls title="' + file.filename + '"" src="' + result.path + '">' +
 | 
			
		||||
                    '<source src="' + result.path + '" type="' + mimeType + '">' +
 | 
			
		||||
                    '</' + type + '>';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Shouldn't reach here, the user should have called CoreMimetypeUtilsProvider#canBeEmbedded.
 | 
			
		||||
            return '';
 | 
			
		||||
            return this.mimetypeUtils.getEmbeddedHtml(module.contents[0], result.path);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,12 +25,7 @@
 | 
			
		||||
        <ion-item text-wrap *ngIf="submission.content">
 | 
			
		||||
            <core-format-text [component]="component" [componentId]="componentId" [text]="submission.content" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"></core-format-text>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
        <ion-item *ngFor="let attachment of submission.attachmentfiles">
 | 
			
		||||
            <!-- Files already attached to the submission. -->
 | 
			
		||||
            <core-file *ngIf="!attachment.name" [file]="attachment" [component]="component" [componentId]="componentId"></core-file>
 | 
			
		||||
            <!-- Files stored in offline to be sent later. -->
 | 
			
		||||
            <core-local-file *ngIf="attachment.name" [file]="attachment"></core-local-file>
 | 
			
		||||
        </ion-item>
 | 
			
		||||
        <core-files [files]="submission.attachmentfiles" [component]="component" [componentId]="componentId"></core-files>
 | 
			
		||||
        <ion-item text-wrap *ngIf="viewDetails && submission.feedbackauthor">
 | 
			
		||||
            <ion-avatar *ngIf="evaluateByProfile" core-user-avatar [user]="evaluateByProfile" item-start [courseId]="courseId" [userId]="evaluateByProfile.id"></ion-avatar>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ import { CoreProgressBarComponent } from './progress-bar/progress-bar';
 | 
			
		||||
import { CoreEmptyBoxComponent } from './empty-box/empty-box';
 | 
			
		||||
import { CoreSearchBoxComponent } from './search-box/search-box';
 | 
			
		||||
import { CoreFileComponent } from './file/file';
 | 
			
		||||
import { CoreFilesComponent } from './files/files';
 | 
			
		||||
import { CoreIconComponent } from './icon/icon';
 | 
			
		||||
import { CoreContextMenuComponent } from './context-menu/context-menu';
 | 
			
		||||
import { CoreContextMenuItemComponent } from './context-menu/context-menu-item';
 | 
			
		||||
@ -67,6 +68,7 @@ import { CoreBSTooltipComponent } from './bs-tooltip/bs-tooltip';
 | 
			
		||||
        CoreEmptyBoxComponent,
 | 
			
		||||
        CoreSearchBoxComponent,
 | 
			
		||||
        CoreFileComponent,
 | 
			
		||||
        CoreFilesComponent,
 | 
			
		||||
        CoreIconComponent,
 | 
			
		||||
        CoreContextMenuComponent,
 | 
			
		||||
        CoreContextMenuItemComponent,
 | 
			
		||||
@ -118,6 +120,7 @@ import { CoreBSTooltipComponent } from './bs-tooltip/bs-tooltip';
 | 
			
		||||
        CoreEmptyBoxComponent,
 | 
			
		||||
        CoreSearchBoxComponent,
 | 
			
		||||
        CoreFileComponent,
 | 
			
		||||
        CoreFilesComponent,
 | 
			
		||||
        CoreIconComponent,
 | 
			
		||||
        CoreContextMenuComponent,
 | 
			
		||||
        CoreContextMenuItemComponent,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								src/components/files/core-files.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/components/files/core-files.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
<ng-container *ngIf="showInline && contentText">
 | 
			
		||||
    <core-format-text [text]="contentText" [filter]="false"></core-format-text>
 | 
			
		||||
</ng-container>
 | 
			
		||||
<ng-container *ngFor="let file of files">
 | 
			
		||||
    <!-- Files already attached to the filearea. -->
 | 
			
		||||
    <core-file *ngIf="!file.name && !file.embedType" [file]="file" [component]="component" [componentId]="componentId" [alwaysDownload]="alwaysDownload" [canDownload]="canDownload" [showSize]="showSize" [showTime]="showTime"></core-file>
 | 
			
		||||
    <!-- Files stored in offline to be sent later. -->
 | 
			
		||||
    <core-local-file *ngIf="file.name && !file.embedType" [file]="file"></core-local-file>
 | 
			
		||||
</ng-container>
 | 
			
		||||
							
								
								
									
										79
									
								
								src/components/files/files.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/components/files/files.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
// (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, OnInit, DoCheck, KeyValueDiffers } from '@angular/core';
 | 
			
		||||
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
 | 
			
		||||
import { CoreUtilsProvider } from '@providers/utils/utils';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Component to render a file list.
 | 
			
		||||
 *
 | 
			
		||||
 * <core-files [files]="files" [component]="component" [componentId]="assign.cmid">
 | 
			
		||||
 * </core-files>
 | 
			
		||||
 */
 | 
			
		||||
@Component({
 | 
			
		||||
    selector: 'core-files',
 | 
			
		||||
    templateUrl: 'core-files.html'
 | 
			
		||||
})
 | 
			
		||||
export class CoreFilesComponent implements OnInit, DoCheck {
 | 
			
		||||
    @Input() files: any[]; // List of files.
 | 
			
		||||
    @Input() component: string; // Component the downloaded files will be linked to.
 | 
			
		||||
    @Input() componentId: string | number; // Component ID.
 | 
			
		||||
    @Input() alwaysDownload?: boolean | string; // Whether it should always display the refresh button when the file is downloaded.
 | 
			
		||||
                                               // Use it for files that you cannot determine if they're outdated or not.
 | 
			
		||||
    @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.
 | 
			
		||||
    @Input() showInline = false; // If true, it will reorder and try to show inline files first.
 | 
			
		||||
 | 
			
		||||
    contentText: string;
 | 
			
		||||
 | 
			
		||||
    protected differ: any; // To detect changes in the data input.
 | 
			
		||||
 | 
			
		||||
    constructor(protected mimetypeUtils: CoreMimetypeUtilsProvider,
 | 
			
		||||
            protected utils: CoreUtilsProvider,
 | 
			
		||||
            differs: KeyValueDiffers) {
 | 
			
		||||
        this.differ = differs.find([]).create();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Component being initialized.
 | 
			
		||||
     */
 | 
			
		||||
    ngOnInit(): void {
 | 
			
		||||
        if (this.utils.isTrueOrOne(this.showInline)) {
 | 
			
		||||
            this.renderInlineFiles();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Detect and act upon changes that Angular can’t or won’t detect on its own (objects and arrays).
 | 
			
		||||
     */
 | 
			
		||||
    ngDoCheck(): void {
 | 
			
		||||
        if (this.utils.isTrueOrOne(this.showInline)) {
 | 
			
		||||
            // Check if there's any change in the extraData object.
 | 
			
		||||
            const changes = this.differ.diff(this.files);
 | 
			
		||||
            if (changes) {
 | 
			
		||||
                this.renderInlineFiles();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected renderInlineFiles(): void {
 | 
			
		||||
        this.contentText = this.files.reduce((previous, file) => {
 | 
			
		||||
            const text = this.mimetypeUtils.getEmbeddedHtml(file);
 | 
			
		||||
 | 
			
		||||
            return text ? previous + '<br>' + text : previous;
 | 
			
		||||
        }, '');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -138,6 +138,40 @@ export class CoreMimetypeUtilsProvider {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the embed type to display an embedded file and mimetype if not found.
 | 
			
		||||
     *
 | 
			
		||||
     * @param file File object.
 | 
			
		||||
     * @paran path Alternative path that will override fileurl from file object.
 | 
			
		||||
     */
 | 
			
		||||
    getEmbeddedHtml(file: any, path?: string): string {
 | 
			
		||||
        let ext;
 | 
			
		||||
 | 
			
		||||
        if (file.mimetype) {
 | 
			
		||||
            ext = this.getExtension(file.mimetype);
 | 
			
		||||
        } else {
 | 
			
		||||
            ext = this.getFileExtension(file.filename);
 | 
			
		||||
            file.mimetype = this.getMimeType(ext);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this.canBeEmbedded(ext)) {
 | 
			
		||||
            file.embedType = this.getExtensionType(ext);
 | 
			
		||||
 | 
			
		||||
            path = path || file.fileurl;
 | 
			
		||||
 | 
			
		||||
            if (file.embedType == 'image') {
 | 
			
		||||
                return '<img src="' + path + '">';
 | 
			
		||||
            }
 | 
			
		||||
            if (file.embedType == 'audio' || file.embedType == 'video') {
 | 
			
		||||
                return '<' + file.embedType + ' controls title="' + file.filename + '" src="' + path + '">' +
 | 
			
		||||
                    '<source src="' + path + '" type="' + file.mimetype + '">' +
 | 
			
		||||
                    '</' + file.embedType + '>';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return '';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the URL of the icon of an extension.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user