Add screenshot support for tasks (copy/paste images directly)

This commit is contained in:
Frederic Guillot
2015-04-12 18:44:42 -04:00
parent 2a150dd3be
commit 3b403a1a4b
33 changed files with 419 additions and 29 deletions

View File

@@ -335,4 +335,19 @@ class Board extends Base
$this->response->redirect($this->helper->url('board', 'show', array('project_id' => $values['project_id'])));
}
/**
* Screenshot popover
*
* @access public
*/
public function screenshot()
{
$task = $this->getTask();
$this->response->html($this->template->render('file/screenshot', array(
'task' => $task,
'redirect' => 'board',
)));
}
}

View File

@@ -10,6 +10,32 @@ namespace Controller;
*/
class File extends Base
{
/**
* Screenshot
*
* @access public
*/
public function screenshot()
{
$task = $this->getTask();
if ($this->request->isPost() && $this->file->uploadScreenshot($task['project_id'], $task['id'], $this->request->getValue('screenshot'))) {
$this->session->flash(t('Screenshot uploaded successfully.'));
if ($this->request->getStringParam('redirect') === 'board') {
$this->response->redirect($this->helper->url('board', 'show', array('project_id' => $task['project_id'])));
}
$this->response->redirect($this->helper->url('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
}
$this->response->html($this->taskLayout('file/screenshot', array(
'task' => $task,
'redirect' => 'task',
)));
}
/**
* File upload form
*
@@ -34,13 +60,11 @@ class File extends Base
{
$task = $this->getTask();
if ($this->file->upload($task['project_id'], $task['id'], 'files') === true) {
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#attachments');
}
else {
if (! $this->file->upload($task['project_id'], $task['id'], 'files')) {
$this->session->flashError(t('Unable to upload the file.'));
$this->response->redirect('?controller=file&action=create&task_id='.$task['id'].'&project_id='.$task['project_id']);
}
$this->response->redirect($this->helper->url('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
}
/**
@@ -59,7 +83,7 @@ class File extends Base
$this->response->binary(file_get_contents($filename));
}
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
$this->response->redirect($this->helper->url('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
}
/**
@@ -140,7 +164,7 @@ class File extends Base
$this->session->flashError(t('Unable to remove this file.'));
}
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
$this->response->redirect($this->helper->url('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])));
}
/**

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -849,10 +849,16 @@ return array(
'Test your device' => 'Testez votre appareil',
'Assign a color when the task is moved to a specific column' => 'Assigner une couleur lorsque la tâche est déplacée dans une colonne spécifique',
'%s via Kanboard' => '%s via Kanboard',
'uploaded by: %s' => 'Télécharger par : %s',
'uploaded on: %s' => 'Télécharger le : %s',
'uploaded by: %s' => 'Téléchargé par %s',
'uploaded on: %s' => 'Téléchargé le %s',
'size: %s' => 'Taille : %s',
'Burndown chart for "%s"' => 'Graphique d\'avancement pour « %s »',
'Burndown chart' => 'Graphique d\'avancement',
'This chart show the task complexity over the time (Work Remaining).' => 'Ce graphique représente la complexité des tâches en fonction du temps (travail restant).',
'Screenshot taken %s' => 'Capture d\'écran prise le %s',
'Add a screenshot' => 'Ajouter une capture d\'écran',
'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => 'Copier/coller des images est uniquement supporté par Mozilla Firefox et Google Chrome.',
'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => 'Prenez une capture d\'écran et appuyez sur CTRL+V ou ⌘+V pour coller ici.',
'Screenshot uploaded successfully.' => 'Capture d\'écran téléchargée avec succès.',
'SEK - Swedish Krona' => 'SEK - Couronne suédoise',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -802,7 +802,6 @@ return array(
'The budget line have been created successfully.' => 'Budgetlinjen har skapats.',
'Unable to create the budget line.' => 'Kunde inte skapa budgetlinjen.',
'Unable to remove this budget line.' => 'Kunde inte ta bort budgetlinjen.',
'SEK - Swedish Krona' => 'SEK - Svensk Krona',
'USD - US Dollar' => 'USD - Amerikanska Dollar',
'Remaining' => 'Återstående',
'Destination column' => 'Målkolumn',
@@ -854,4 +853,10 @@ return array(
'Burndown chart for "%s"' => 'Burndown diagram för "%s"',
'Burndown chart' => 'Burndown diagram',
'This chart show the task complexity over the time (Work Remaining).' => 'Diagrammet visar uppgiftens svårighet över tid (återstående arbete).',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
'SEK - Swedish Krona' => 'SEK - Svensk Krona',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -853,4 +853,10 @@ return array(
// 'Burndown chart for "%s"' => '',
// 'Burndown chart' => '',
// 'This chart show the task complexity over the time (Work Remaining).' => '',
// 'Screenshot taken %s' => '',
// 'Add a screenshot' => '',
// 'Copy and paste images are only supported with Mozilla Firefox and Google Chrome.' => '',
// 'Take a screenshot and press CTRL+V or ⌘+V to paste here.' => '',
// 'Screenshot uploaded successfully.' => '',
// 'SEK - Swedish Krona' => '',
);

View File

@@ -40,6 +40,7 @@ class Config extends Base
'INR' => t('INR - Indian Rupee'),
'JPY' => t('JPY - Japanese Yen'),
'RSD' => t('RSD - Serbian dinar'),
'SEK' => t('SEK - Swedish Krona'),
);
}

View File

@@ -248,9 +248,9 @@ class File extends Base
* Handle file upload
*
* @access public
* @param integer $project_id Project id
* @param integer $task_id Task id
* @param string $form_name File form name
* @param integer $project_id Project id
* @param integer $task_id Task id
* @param string $form_name File form name
* @return bool
*/
public function upload($project_id, $task_id, $form_name)
@@ -287,6 +287,38 @@ class File extends Base
return count(array_unique($result)) === 1;
}
/**
* Handle screenshot upload
*
* @access public
* @param integer $project_id Project id
* @param integer $task_id Task id
* @param string $blob Base64 encoded image
* @return bool
*/
public function uploadScreenshot($project_id, $task_id, $blob)
{
$data = base64_decode($blob);
if (empty($data)) {
return false;
}
$original_filename = e('Screenshot taken %s', dt('%B %e, %Y at %k:%M %p', time()));
$destination_filename = $this->generatePath($project_id, $task_id, $original_filename);
@mkdir(FILES_DIR.dirname($destination_filename), 0755, true);
@file_put_contents(FILES_DIR.$destination_filename, $data);
return $this->create(
$task_id,
$original_filename,
$destination_filename,
true,
strlen($data)
);
}
/**
* Generate a jpeg thumbnail from an image (output directly the image)
*

View File

@@ -8,6 +8,7 @@
<li><i class="fa fa-comment-o"></i> <?= $this->a(t('Add a comment'), 'comment', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'task-board-popover') ?></li>
<li><i class="fa fa-code-fork"></i> <?= $this->a(t('Add a link'), 'tasklink', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'task-board-popover') ?></li>
<li><i class="fa fa-pencil-square-o"></i> <?= $this->a(t('Edit this task'), 'task', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'task-board-popover') ?></li>
<li><i class="fa fa-camera"></i> <?= $this->a(t('Add a screenshot'), 'board', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'task-board-popover') ?></li>
<li><i class="fa fa-close"></i> <?= $this->a(t('Close this task'), 'task', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board'), false, 'task-board-popover') ?></li>
</ul>
</span>

View File

@@ -0,0 +1,19 @@
<div class="page-header">
<h2><?= t('Add a screenshot') ?></h2>
</div>
<div id="screenshot-zone">
<p id="screenshot-inner"><?= t('Take a screenshot and press CTRL+V or ⌘+V to paste here.') ?></p>
</div>
<form action="<?= $this->u('file', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => $redirect)) ?>" method="post">
<input type="hidden" name="screenshot"/>
<?= $this->formCsrf() ?>
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'close-popover') ?>
</div>
</form>
<p class="alert alert-info"><?= t('Copy and paste images are only supported with Mozilla Firefox and Google Chrome.') ?></p>

View File

@@ -36,6 +36,9 @@
<li>
<?= $this->a(t('Attach a document'), 'file', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
<?= $this->a(t('Add a screenshot'), 'file', 'screenshot', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>
<li>
<?= $this->a(t('Duplicate'), 'task', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li>