Closes #194: PDF viewer

This commit is contained in:
Benjamin Gamard 2018-03-09 11:18:19 +01:00
parent 6f27b9c13f
commit 63c7e9710b
3 changed files with 90 additions and 25 deletions

View File

@ -3,58 +3,77 @@
/** /**
* File modal view controller. * File modal view controller.
*/ */
angular.module('docs').controller('FileModalView', function($uibModalInstance, $scope, $state, $stateParams, Restangular, $transitions) { angular.module('docs').controller('FileModalView', function ($uibModalInstance, $scope, $state, $stateParams, $sce, Restangular, $transitions) {
// Load files // Load files
Restangular.one('file/list').get({ id: $stateParams.id }).then(function(data) { Restangular.one('file/list').get({ id: $stateParams.id }).then(function (data) {
$scope.files = data.files; $scope.files = data.files;
// Search current file // Search current file
_.each($scope.files, function(value) { _.each($scope.files, function (value) {
if (value.id === $stateParams.fileId) { if (value.id === $stateParams.fileId) {
$scope.file = value; $scope.file = value;
$scope.trustedFileUrl = $sce.trustAsResourceUrl('../api/file/' + $stateParams.fileId + '/data');
} }
}); });
}); });
/** /**
* Navigate to the next file. * Return the next file.
*/ */
$scope.nextFile = function() { $scope.nextFile = function () {
_.each($scope.files, function(value, key) { var next = undefined;
_.each($scope.files, function (value, key) {
if (value.id === $stateParams.fileId) { if (value.id === $stateParams.fileId) {
var next = $scope.files[key + 1]; next = $scope.files[key + 1];
if (next) {
$state.go('^.file', { id: $stateParams.id, fileId: next.id });
}
} }
}); });
return next;
};
/**
* Return the previous file.
*/
$scope.previousFile = function () {
var previous = undefined;
_.each($scope.files, function (value, key) {
if (value.id === $stateParams.fileId) {
previous = $scope.files[key - 1];
}
});
return previous;
};
/**
* Navigate to the next file.
*/
$scope.goNextFile = function () {
var next = $scope.nextFile();
if (next) {
$state.go('^.file', { id: $stateParams.id, fileId: next.id });
}
}; };
/** /**
* Navigate to the previous file. * Navigate to the previous file.
*/ */
$scope.previousFile = function() { $scope.goPreviousFile = function () {
_.each($scope.files, function(value, key) { var previous = $scope.previousFile();
if (value.id === $stateParams.fileId) { if (previous) {
var previous = $scope.files[key - 1]; $state.go('^.file', { id: $stateParams.id, fileId: previous.id });
if (previous) { }
$state.go('^.file', { id: $stateParams.id, fileId: previous.id });
}
}
});
}; };
/** /**
* Open the file in a new window. * Open the file in a new window.
*/ */
$scope.openFile = function() { $scope.openFile = function () {
window.open('../api/file/' + $stateParams.fileId + '/data'); window.open('../api/file/' + $stateParams.fileId + '/data');
}; };
/** /**
* Print the file. * Print the file.
*/ */
$scope.printFile = function() { $scope.printFile = function () {
var popup = window.open('../api/file/' + $stateParams.fileId + '/data', '_blank'); var popup = window.open('../api/file/' + $stateParams.fileId + '/data', '_blank');
popup.onload = function () { popup.onload = function () {
popup.print(); popup.print();
@ -80,4 +99,11 @@ angular.module('docs').controller('FileModalView', function($uibModalInstance, $
} }
off(); off();
}); });
/**
* Return true if we can display the preview image.
*/
$scope.canDisplayPreview = function () {
return $scope.file && $scope.file.mimetype !== 'application/pdf';
};
}); });

View File

@ -6,8 +6,19 @@
</div> </div>
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-default" ng-click="previousFile()">{{ 'file.view.previous' | translate }}</button> <button type="button" class="btn btn-default"
<button type="button" class="btn btn-default" ng-click="nextFile()">{{ 'file.view.next' | translate }}</button> ng-style="{ 'visibility': previousFile() ? 'visible' : 'hidden' }"
ng-click="goPreviousFile()">
{{ 'file.view.previous' | translate }}
</button>
<button type="button" class="btn btn-default"
ng-style="{ 'visibility': nextFile() ? 'visible' : 'hidden' }"
ng-click="goNextFile()">
{{ 'file.view.next' | translate }}
</button>
<button type="button" class="btn btn-placeholder" style="visibility: hidden">
&nbsp;
</button>
</div> </div>
<div class="btn-group pull-right"> <div class="btn-group pull-right">
@ -21,16 +32,24 @@
</div> </div>
<div class="text-center" style="position: relative;" ng-if="$stateParams.fileId"> <div class="text-center" style="position: relative;" ng-if="$stateParams.fileId">
<!-- Standard preview -->
<img ng-src="../api/file/{{ $stateParams.fileId }}/data?size=web" <img ng-src="../api/file/{{ $stateParams.fileId }}/data?size=web"
ng-init="error = false" ng-init="error = false"
img-error="error = true" img-error="error = true"
ng-show="!error" /> ng-show="!error && canDisplayPreview()" />
<a href class="video-overlay" ng-if="file.mimetype.substring(0, 6) == 'video/'"
<!-- Video player -->
<a href class="video-overlay" ng-if="!error && file.mimetype.substring(0, 6) == 'video/'"
ng-init="videoPlayer = false" ng-click="videoPlayer = true"> ng-init="videoPlayer = false" ng-click="videoPlayer = true">
<span class="fas fa-play-circle" ng-if="!videoPlayer"></span> <span class="fas fa-play-circle" ng-if="!videoPlayer"></span>
<video ng-if="videoPlayer" autoplay="autoplay" loop="loop" <video ng-if="videoPlayer" autoplay="autoplay" loop="loop"
controls="controls" ng-src="../api/file/{{ $stateParams.fileId }}/data"></video> controls="controls" ng-src="../api/file/{{ $stateParams.fileId }}/data"></video>
</a> </a>
<!-- PDF viewer -->
<iframe ng-src="{{ trustedFileUrl }}" class="pdf-viewer" scrolling="yes" ng-if="!error && file.mimetype == 'application/pdf'"></iframe>
<!-- File not found -->
<p class="well-lg" ng-show="error"> <p class="well-lg" ng-show="error">
<span class="fas fa-exclamation-triangle"></span> <span class="fas fa-exclamation-triangle"></span>
{{ 'file.view.not_found' | translate }} {{ 'file.view.not_found' | translate }}

View File

@ -422,6 +422,18 @@ input[readonly].share-link {
} }
} }
// PDF viewer
.pdf-viewer {
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 80vh;
}
// Vertical alignment // Vertical alignment
.vertical-center { .vertical-center {
min-height: 100vh; min-height: 100vh;
@ -619,3 +631,11 @@ input[readonly].share-link {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
} }
// Button placeholder
.btn-placeholder {
visibility: hidden;
width: 0;
padding-left: 0;
padding-right: 0;
}