Add file preview for Markdown and text files

This commit is contained in:
Frederic Guillot 2016-02-16 22:06:53 -05:00
parent 4961805e0f
commit 9249498503
11 changed files with 109 additions and 38 deletions

View File

@ -12,6 +12,30 @@ use Kanboard\Core\ObjectStorage\ObjectStorageException;
*/
class FileViewer extends Base
{
/**
* Get file content from object storage
*
* @access private
* @param array $file
* @return string
*/
private function getFileContent(array $file)
{
$content = '';
try {
if ($file['is_image'] == 0) {
$content = $this->objectStorage->get($file['path']);
}
} catch (ObjectStorageException $e) {
$this->logger->error($e->getMessage());
}
return $content;
}
/**
* Show file content in a popover
*
@ -20,6 +44,7 @@ class FileViewer extends Base
public function show()
{
$file = $this->getFile();
$type = $this->helper->file->getPreviewType($file['name']);
$params = array('file_id' => $file['id'], 'project_id' => $this->request->getIntegerParam('project_id'));
if ($file['model'] === 'taskFile') {
@ -29,6 +54,8 @@ class FileViewer extends Base
$this->response->html($this->template->render('file_viewer/show', array(
'file' => $file,
'params' => $params,
'type' => $type,
'content' => $this->getFileContent($file),
)));
}

View File

@ -82,4 +82,26 @@ class File extends \Kanboard\Core\Base
return 'image/jpeg';
}
}
/**
* Get the preview type
*
* @access public
* @param string $filename
* @return string
*/
public function getPreviewType($filename)
{
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
switch ($extension) {
case 'md':
case 'markdown':
return 'markdown';
case 'txt':
return 'text';
}
return null;
}
}

View File

@ -81,6 +81,7 @@ class AuthenticationProvider implements ServiceProviderInterface
$acl->add('Project', array('share', 'integrations', 'notifications', 'duplicate', 'disable', 'enable', 'remove'), Role::PROJECT_MANAGER);
$acl->add('ProjectPermission', '*', Role::PROJECT_MANAGER);
$acl->add('ProjectEdit', '*', Role::PROJECT_MANAGER);
$acl->add('ProjectFile', '*', Role::PROJECT_MEMBER);
$acl->add('Projectuser', '*', Role::PROJECT_MANAGER);
$acl->add('Subtask', '*', Role::PROJECT_MEMBER);
$acl->add('SubtaskRestriction', '*', Role::PROJECT_MEMBER);

View File

@ -1,8 +1,14 @@
<div class="page-header">
<h2><?= $this->e($file['name']) ?></h2>
<div class="task-file-viewer">
<?php if ($file['is_image']): ?>
<img src="<?= $this->url->href('FileViewer', 'image', $params) ?>" alt="<?= $this->e($file['name']) ?>">
<?php endif ?>
</div>
</div>
<div class="file-viewer">
<?php if ($file['is_image']): ?>
<img src="<?= $this->url->href('FileViewer', 'image', $params) ?>" alt="<?= $this->e($file['name']) ?>">
<?php elseif ($type === 'markdown'): ?>
<article class="markdown">
<?= $this->text->markdown($content) ?>
</article>
<?php elseif ($type === 'text'): ?>
<pre><?= $content ?></pre>
<?php endif ?>
</div>

View File

@ -24,16 +24,16 @@
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-text"><?= $this->e($file['name']) ?> <i class="fa fa-caret-down"></i></a>
<ul>
<li>
<i class="fa fa-download fa-fw"></i>
<?= $this->url->link(t('Download'), 'FileViewer', 'download', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('ProjectFile', 'remove', $project['id'])): ?>
<li>
<i class="fa fa-trash fa-fw"></i>
<?= $this->url->link(t('Remove'), 'ProjectFile', 'confirm', array('project_id' => $project['id'], 'file_id' => $file['id']), false, 'popover') ?>
</li>
<?php endif ?>
<li>
<i class="fa fa-download fa-fw"></i>
<?= $this->url->link(t('Download'), 'FileViewer', 'download', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
</li>
</ul>
</div>
</div>
@ -64,16 +64,22 @@
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-text"><?= $this->e($file['name']) ?> <i class="fa fa-caret-down"></i></a>
<ul>
<?php if ($this->user->hasProjectAccess('ProjectFile', 'remove', $project['id'])): ?>
<?php if ($this->file->getPreviewType($file['name']) !== null): ?>
<li>
<i class="fa fa-trash fa-fw"></i>
<?= $this->url->link(t('Remove'), 'ProjectFile', 'confirm', array('project_id' => $project['id'], 'file_id' => $file['id']), false, 'popover') ?>
<i class="fa fa-eye fa-fw"></i>
<?= $this->url->link(t('View'), 'FileViewer', 'show', array('project_id' => $project['id'], 'file_id' => $file['id']), false, 'popover') ?>
</li>
<?php endif ?>
<li>
<i class="fa fa-download fa-fw"></i>
<?= $this->url->link(t('Download'), 'FileViewer', 'download', array('project_id' => $project['id'], 'file_id' => $file['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('ProjectFile', 'remove', $project['id'])): ?>
<li>
<i class="fa fa-trash fa-fw"></i>
<?= $this->url->link(t('Remove'), 'ProjectFile', 'confirm', array('project_id' => $project['id'], 'file_id' => $file['id']), false, 'popover') ?>
</li>
<?php endif ?>
</ul>
</div>
</td>

View File

@ -14,16 +14,16 @@
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-text"><?= $this->e($file['name']) ?> <i class="fa fa-caret-down"></i></a>
<ul>
<li>
<i class="fa fa-download fa-fw"></i>
<?= $this->url->link(t('Download'), 'FileViewer', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('TaskFile', 'remove', $task['project_id'])): ?>
<li>
<i class="fa fa-trash fa-fw"></i>
<?= $this->url->link(t('Remove'), 'TaskFile', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>
</li>
<?php endif ?>
<li>
<i class="fa fa-download fa-fw"></i>
<?= $this->url->link(t('Download'), 'FileViewer', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
</li>
</ul>
</div>
</div>
@ -54,16 +54,22 @@
<div class="dropdown">
<a href="#" class="dropdown-menu dropdown-menu-link-text"><?= $this->e($file['name']) ?> <i class="fa fa-caret-down"></i></a>
<ul>
<?php if ($this->user->hasProjectAccess('TaskFile', 'remove', $task['project_id'])): ?>
<?php if ($this->file->getPreviewType($file['name']) !== null): ?>
<li>
<i class="fa fa-trash fa-fw"></i>
<?= $this->url->link(t('Remove'), 'TaskFile', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>
<i class="fa fa-eye fa-fw"></i>
<?= $this->url->link(t('View'), 'FileViewer', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>
</li>
<?php endif ?>
<li>
<i class="fa fa-download fa-fw"></i>
<?= $this->url->link(t('Download'), 'FileViewer', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
</li>
<?php if ($this->user->hasProjectAccess('TaskFile', 'remove', $task['project_id'])): ?>
<li>
<i class="fa fa-trash fa-fw"></i>
<?= $this->url->link(t('Remove'), 'TaskFile', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'popover') ?>
</li>
<?php endif ?>
</ul>
</div>
</td>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -14,7 +14,7 @@
border: 1px solid #efefef;
border-radius: 5px;
margin-bottom: 20px;
box-shadow: 2px 2px 5px -2px rgba(0, 0, 0, 0.55);
box-shadow: 4px 2px 10px -6px rgba(0,0,0,0.55);
margin-right: 15px;
}
@ -44,3 +44,13 @@
margin-top: 8px;
margin-bottom: 5px;
}
.file-viewer {
position: relative;
}
.file-viewer img {
max-width: 95%;
max-height: 85%;
margin-top: 10px;
}

View File

@ -205,22 +205,6 @@ span.task-board-date-overdue {
height: 300px;
}
.task-file-viewer {
position: relative;
}
.task-file-viewer img {
max-width: 95%;
max-height: 85%;
margin-top: 10px;
}
.task-time-form {
margin-top: 10px;
margin-bottom: 25px;
padding: 3px;
}
.task-link-closed {
text-decoration: line-through;
}

View File

@ -24,4 +24,13 @@ class FileHelperTest extends Base
$this->assertEquals('image/jpeg', $helper->getImageMimeType('My File.bmp'));
$this->assertEquals('image/jpeg', $helper->getImageMimeType('My File'));
}
public function testGetPreviewType()
{
$helper = new File($this->container);
$this->assertEquals('text', $helper->getPreviewType('test.txt'));
$this->assertEquals('markdown', $helper->getPreviewType('test.markdown'));
$this->assertEquals('md', $helper->getPreviewType('test.md'));
$this->assertEquals(null, $helper->getPreviewType('test.doc'));
}
}