diff --git a/logo/star.svg b/logo/star.svg new file mode 100644 index 0000000..ff0ae76 --- /dev/null +++ b/logo/star.svg @@ -0,0 +1,172 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/IDF/Form/IssueCreate.php b/src/IDF/Form/IssueCreate.php index 8f26c0b..497d910 100644 --- a/src/IDF/Form/IssueCreate.php +++ b/src/IDF/Form/IssueCreate.php @@ -220,9 +220,6 @@ class IDF_Form_IssueCreate extends Pluf_Form foreach ($tags as $tag) { $issue->setAssoc($tag); } - $issue->setAssoc($this->user); // the user is - // automatically - // interested. // add the first comment $comment = new IDF_IssueComment(); $comment->issue = $issue; diff --git a/src/IDF/Form/IssueUpdate.php b/src/IDF/Form/IssueUpdate.php index ae4b274..1fb186f 100644 --- a/src/IDF/Form/IssueUpdate.php +++ b/src/IDF/Form/IssueUpdate.php @@ -253,6 +253,7 @@ class IDF_Form_IssueUpdate extends IDF_Form_IssueCreate $comment->changes = $changes; $comment->create(); $this->issue->update(); + $this->issue->setAssoc($this->user); // interested user. return $this->issue; } throw new Exception(__('Cannot save the model from an invalid form.')); diff --git a/src/IDF/Views/Issue.php b/src/IDF/Views/Issue.php index eaee67d..3a99df2 100644 --- a/src/IDF/Views/Issue.php +++ b/src/IDF/Views/Issue.php @@ -46,7 +46,8 @@ class IDF_Views_Issue $pag = new Pluf_Paginator(new IDF_Issue()); $pag->class = 'recent-issues'; $pag->item_extra_props = array('project_m' => $prj, - 'shortname' => $prj->shortname); + 'shortname' => $prj->shortname, + 'current_user' => $request->user); $pag->summary = __('This table shows the open issues.'); $otags = $prj->getTagIdsByStatus('open'); if (count($otags) == 0) $otags[] = 0; @@ -103,7 +104,8 @@ class IDF_Views_Issue $pag = new Pluf_Paginator(new IDF_Issue()); $pag->class = 'recent-issues'; $pag->item_extra_props = array('project_m' => $prj, - 'shortname' => $prj->shortname); + 'shortname' => $prj->shortname, + 'current_user' => $request->user); $pag->summary = __('This table shows the open issues.'); $pag->forced_where = $f_sql; $pag->action = array('IDF_Views_Issue::myIssues', array($prj->shortname, $match[2])); @@ -192,7 +194,9 @@ class IDF_Views_Issue array($prj->shortname, $issue->id)); $title = Pluf_Template::markSafe(sprintf(__('Issue %d: %s'), $url, $issue->id, $issue->summary)); $form = false; // The form is available only if logged in. + $starred = false; if (!$request->user->isAnonymous()) { + $starred = Pluf_Model_InArray($request->user, $issue->get_interested_list()); $params = array( 'project' => $prj, 'user' => $request->user, @@ -248,10 +252,11 @@ class IDF_Views_Issue $arrays = self::autoCompleteArrays($prj); return Pluf_Shortcuts_RenderToResponse('issues/view.html', array_merge( - array('project' => $prj, + array( 'issue' => $issue, 'comments' => $comments, 'form' => $form, + 'starred' => $starred, 'page_title' => $title, ), $arrays), @@ -274,7 +279,8 @@ class IDF_Views_Issue $pag = new Pluf_Paginator(new IDF_Issue()); $pag->class = 'recent-issues'; $pag->item_extra_props = array('project_m' => $prj, - 'shortname' => $prj->shortname); + 'shortname' => $prj->shortname, + 'current_user' => $request->user); $pag->summary = __('This table shows the closed issues.'); $otags = $prj->getTagIdsByStatus('closed'); if (count($otags) == 0) $otags[] = 0; @@ -330,7 +336,8 @@ class IDF_Views_Issue $pag->model_view = 'join_tags'; $pag->class = 'recent-issues'; $pag->item_extra_props = array('project_m' => $prj, - 'shortname' => $prj->shortname); + 'shortname' => $prj->shortname, + 'current_user' => $request->user); $pag->summary = sprintf(__('This table shows the issues with label %s.'), (string) $tag); $otags = $prj->getTagIdsByStatus($status); if (count($otags) == 0) $otags[] = 0; @@ -366,6 +373,31 @@ class IDF_Views_Issue } /** + * Star/Unstar an issue. + */ + public $star_precond = array('IDF_Precondition::accessIssues', + 'Pluf_Precondition::loginRequired'); + public function star($request, $match) + { + $prj = $request->project; + $issue = Pluf_Shortcuts_GetObjectOr404('IDF_Issue', $match[2]); + $prj->inOr404($issue); + if ($request->method == 'POST') { + $starred = Pluf_Model_InArray($request->user, $issue->get_interested_list()); + if ($starred) { + $issue->delAssoc($request->user); + $request->user->setMessage(__('The issue has been removed from your watch list.')); + } else { + $issue->setAssoc($request->user); + $request->user->setMessage(__('The issue has been added to your watch list.')); + } + } + $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view', + array($prj->shortname, $issue->id)); + return new Pluf_HTTP_Response_Redirect($url); + } + + /** * Create the autocomplete arrays for the little AJAX stuff. */ public static function autoCompleteArrays($project) @@ -432,11 +464,15 @@ function IDF_Views_Issue_SummaryAndLabels($field, $issue, $extra='') array($issue->shortname, $tag->id, 'open')); $tags[] = sprintf('%s', $url, Pluf_esc((string) $tag)); } + $s = ''; + if (Pluf_Model_InArray($issue->current_user, $issue->get_interested_list())) { + $s = ' '; + } $out = ''; if (count($tags)) { $out = '
'.implode(', ', $tags).''; } - return sprintf('%s', $edit, Pluf_esc($issue->summary)).$out; + return $s.sprintf('%s', $edit, Pluf_esc($issue->summary)).$out; } /** diff --git a/src/IDF/conf/views.php b/src/IDF/conf/views.php index 1a1b5b8..6fa1a85 100644 --- a/src/IDF/conf/views.php +++ b/src/IDF/conf/views.php @@ -85,6 +85,12 @@ $ctl[] = array('regex' => '#^/p/(\w+)/issues/(\d+)/$#', 'model' => 'IDF_Views_Issue', 'method' => 'view'); +$ctl[] = array('regex' => '#^/p/(\w+)/issues/(\d+)/star/$#', + 'base' => $base, + 'priority' => 4, + 'model' => 'IDF_Views_Issue', + 'method' => 'star'); + $ctl[] = array('regex' => '#^/p/(\w+)/issues/status/(\w+)/$#', 'base' => $base, 'priority' => 4, diff --git a/src/IDF/templates/base.html b/src/IDF/templates/base.html index 34fd3bd..e5a5019 100644 --- a/src/IDF/templates/base.html +++ b/src/IDF/templates/base.html @@ -51,7 +51,7 @@ {block subtabs}{if $user.isAnonymous()} | {aurl 'url', 'IDF_Views::login'}{blocktrans}Sign in or create your account to create issues or add comments{/blocktrans}{/if}{/block} -

{block title}{$page_title}{/block}

+

{block titleicon}{/block}{block title}{$page_title}{/block}

diff --git a/src/IDF/templates/issues/view.html b/src/IDF/templates/issues/view.html index 3926f0a..b4e0f90 100644 --- a/src/IDF/templates/issues/view.html +++ b/src/IDF/templates/issues/view.html @@ -1,4 +1,5 @@ {extends "issues/base.html"} +{block titleicon}{if $form}
{/if}{/block} {block body} {assign $i = 0} {assign $nc = $comments.count()} diff --git a/www/media/idf/css/style.css b/www/media/idf/css/style.css index 7555c24..8b9e3a0 100644 --- a/www/media/idf/css/style.css +++ b/www/media/idf/css/style.css @@ -56,6 +56,10 @@ div.context { /** * Form */ +form.star { + display: inline; +} + table.form th, table.form td { border: none; vertical-align: top; diff --git a/www/media/idf/img/star-grey.png b/www/media/idf/img/star-grey.png new file mode 100644 index 0000000..20339ac Binary files /dev/null and b/www/media/idf/img/star-grey.png differ diff --git a/www/media/idf/img/star.png b/www/media/idf/img/star.png new file mode 100644 index 0000000..96156b1 Binary files /dev/null and b/www/media/idf/img/star.png differ