From 8aeb7aa52587dcb2966de1cc16916dd3be708da2 Mon Sep 17 00:00:00 2001 From: Chad Little Date: Fri, 18 Nov 2016 13:23:41 -0800 Subject: [PATCH] Show file comments on file lightboxes Summary: Basic work in progress, but should show timeline comments for files when in lightbox mode. Looks reasonable. Test Plan: click on images, see comments from timeline. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T3612 Differential Revision: https://secure.phabricator.com/D16896 --- resources/celerity/map.php | 42 ++-- resources/celerity/packages.php | 3 +- src/__phutil_library_map__.php | 2 + .../PhabricatorFilesApplication.php | 1 + .../PhabricatorFileLightboxController.php | 43 ++++ .../PhabricatorEmbedFileRemarkupRule.php | 6 +- .../PhabricatorApplicationTransactionView.php | 4 + .../control/PhabricatorRemarkupControl.php | 2 +- src/view/layout/PhabricatorFileLinkView.php | 19 +- src/view/page/PhabricatorStandardPageView.php | 13 +- webroot/rsrc/css/aphront/dialog-view.css | 5 + webroot/rsrc/css/phui/phui-comment-panel.css | 60 ++++++ .../phui-lightbox.css} | 72 ++++++- .../js/core/behavior-lightbox-attachments.js | 185 +++++++++++++----- 14 files changed, 371 insertions(+), 86 deletions(-) create mode 100644 src/applications/files/controller/PhabricatorFileLightboxController.php create mode 100644 webroot/rsrc/css/phui/phui-comment-panel.css rename webroot/rsrc/css/{aphront/lightbox-attachment.css => phui/phui-lightbox.css} (55%) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index e10c935bf4..b2fee217de 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -9,8 +9,8 @@ return array( 'names' => array( 'conpherence.pkg.css' => '0b64e988', 'conpherence.pkg.js' => '6249a1cf', - 'core.pkg.css' => '2f1ecc57', - 'core.pkg.js' => 'f0648ee7', + 'core.pkg.css' => '347113ea', + 'core.pkg.js' => '40e98735', 'darkconsole.pkg.js' => 'e7393ebb', 'differential.pkg.css' => 'a4ba74b5', 'differential.pkg.js' => '634399e9', @@ -21,8 +21,7 @@ return array( 'maniphest.pkg.js' => '949a7498', 'rsrc/css/aphront/aphront-bars.css' => '231ac33c', 'rsrc/css/aphront/dark-console.css' => 'f54bf286', - 'rsrc/css/aphront/dialog-view.css' => 'c076ef55', - 'rsrc/css/aphront/lightbox-attachment.css' => '90a84e83', + 'rsrc/css/aphront/dialog-view.css' => '49b2a8a3', 'rsrc/css/aphront/list-filter-view.css' => '5d6f0526', 'rsrc/css/aphront/multi-column.css' => '84cc6640', 'rsrc/css/aphront/notification.css' => '3f6c89c9', @@ -133,6 +132,7 @@ return array( 'rsrc/css/phui/phui-chart.css' => '6bf6f78e', 'rsrc/css/phui/phui-cms.css' => 'be43c8a8', 'rsrc/css/phui/phui-comment-form.css' => '4ecc56ef', + 'rsrc/css/phui/phui-comment-panel.css' => '85113e6a', 'rsrc/css/phui/phui-crumbs-view.css' => '195ac419', 'rsrc/css/phui/phui-curtain-view.css' => '947bf1a4', 'rsrc/css/phui/phui-document-pro.css' => 'c354e312', @@ -151,6 +151,7 @@ return array( 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', 'rsrc/css/phui/phui-info-view.css' => 'ec92802a', 'rsrc/css/phui/phui-invisible-character-view.css' => '6993d9f0', + 'rsrc/css/phui/phui-lightbox.css' => 'e17ce2bd', 'rsrc/css/phui/phui-list.css' => '9da2aa00', 'rsrc/css/phui/phui-object-box.css' => '6b487c57', 'rsrc/css/phui/phui-object-item-list-view.css' => '87278fa0', @@ -504,7 +505,7 @@ return array( 'rsrc/js/core/behavior-hovercard.js' => 'bcaccd64', 'rsrc/js/core/behavior-keyboard-pager.js' => 'a8da01f0', 'rsrc/js/core/behavior-keyboard-shortcuts.js' => '01fca1f0', - 'rsrc/js/core/behavior-lightbox-attachments.js' => 'e50dcfc0', + 'rsrc/js/core/behavior-lightbox-attachments.js' => 'ec949017', 'rsrc/js/core/behavior-line-linker.js' => '1499a8cb', 'rsrc/js/core/behavior-more.js' => 'a80d0378', 'rsrc/js/core/behavior-object-selector.js' => 'e0ec7f2f', @@ -544,7 +545,7 @@ return array( 'almanac-css' => 'dbb9b3af', 'aphront-bars' => '231ac33c', 'aphront-dark-console-css' => 'f54bf286', - 'aphront-dialog-view-css' => 'c076ef55', + 'aphront-dialog-view-css' => '49b2a8a3', 'aphront-list-filter-view-css' => '5d6f0526', 'aphront-multi-column-view-css' => '84cc6640', 'aphront-panel-view-css' => '8427b78d', @@ -650,7 +651,7 @@ return array( 'javelin-behavior-history-install' => '7ee2b591', 'javelin-behavior-icon-composer' => '8499b6ab', 'javelin-behavior-launch-icon-composer' => '48086888', - 'javelin-behavior-lightbox-attachments' => 'e50dcfc0', + 'javelin-behavior-lightbox-attachments' => 'ec949017', 'javelin-behavior-line-chart' => 'e4232876', 'javelin-behavior-load-blame' => '42126667', 'javelin-behavior-maniphest-batch-editor' => '782ab6e7', @@ -766,7 +767,6 @@ return array( 'javelin-workboard-column' => '21df4ff5', 'javelin-workboard-controller' => '55baf5ed', 'javelin-workflow' => '1e911d0f', - 'lightbox-attachment-css' => '90a84e83', 'maniphest-batch-editor' => 'b0f0b6d5', 'maniphest-report-css' => '9b9580b7', 'maniphest-task-edit-css' => 'fda62a9b', @@ -847,6 +847,7 @@ return array( 'phui-chart-css' => '6bf6f78e', 'phui-cms-css' => 'be43c8a8', 'phui-comment-form-css' => '4ecc56ef', + 'phui-comment-panel-css' => '85113e6a', 'phui-crumbs-view-css' => '195ac419', 'phui-curtain-view-css' => '947bf1a4', 'phui-document-summary-view-css' => '9ca48bdf', @@ -868,6 +869,7 @@ return array( 'phui-info-view-css' => 'ec92802a', 'phui-inline-comment-view-css' => '5953c28e', 'phui-invisible-character-view-css' => '6993d9f0', + 'phui-lightbox-css' => 'e17ce2bd', 'phui-list-view-css' => '9da2aa00', 'phui-object-box-css' => '6b487c57', 'phui-object-item-list-view-css' => '87278fa0', @@ -1579,6 +1581,9 @@ return array( 'javelin-dom', 'javelin-stratcom', ), + '85113e6a' => array( + 'phui-timeline-view-css', + ), '85ee8ce6' => array( 'aphront-dialog-view-css', ), @@ -2102,15 +2107,6 @@ return array( 'javelin-behavior', 'javelin-dom', ), - 'e50dcfc0' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - 'javelin-mask', - 'javelin-util', - 'phuix-icon-view', - 'phabricator-busy', - ), 'e5339c43' => array( 'javelin-behavior', 'javelin-dom', @@ -2131,6 +2127,15 @@ return array( 'javelin-dom', 'phabricator-draggable-list', ), + 'ec949017' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-mask', + 'javelin-util', + 'phuix-icon-view', + 'phabricator-busy', + ), 'edd1ba66' => array( 'javelin-behavior', 'javelin-stratcom', @@ -2283,7 +2288,8 @@ return array( 'phabricator-main-menu-view', 'phabricator-notification-css', 'phabricator-notification-menu-css', - 'lightbox-attachment-css', + 'phui-lightbox-css', + 'phui-comment-panel-css', 'phui-header-view-css', 'phabricator-nav-view-css', 'phui-basic-nav-view-css', diff --git a/resources/celerity/packages.php b/resources/celerity/packages.php index 8e7d339902..affa180dc1 100644 --- a/resources/celerity/packages.php +++ b/resources/celerity/packages.php @@ -111,7 +111,8 @@ return array( 'phabricator-main-menu-view', 'phabricator-notification-css', 'phabricator-notification-menu-css', - 'lightbox-attachment-css', + 'phui-lightbox-css', + 'phui-comment-panel-css', 'phui-header-view-css', 'phabricator-nav-view-css', 'phui-basic-nav-view-css', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 5b93d7d176..fe026df777 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2653,6 +2653,7 @@ phutil_register_library_map(array( 'PhabricatorFileImageProxyController' => 'applications/files/controller/PhabricatorFileImageProxyController.php', 'PhabricatorFileImageTransform' => 'applications/files/transform/PhabricatorFileImageTransform.php', 'PhabricatorFileInfoController' => 'applications/files/controller/PhabricatorFileInfoController.php', + 'PhabricatorFileLightboxController' => 'applications/files/controller/PhabricatorFileLightboxController.php', 'PhabricatorFileLinkView' => 'view/layout/PhabricatorFileLinkView.php', 'PhabricatorFileListController' => 'applications/files/controller/PhabricatorFileListController.php', 'PhabricatorFileQuery' => 'applications/files/query/PhabricatorFileQuery.php', @@ -7623,6 +7624,7 @@ phutil_register_library_map(array( 'PhabricatorFileImageProxyController' => 'PhabricatorFileController', 'PhabricatorFileImageTransform' => 'PhabricatorFileTransform', 'PhabricatorFileInfoController' => 'PhabricatorFileController', + 'PhabricatorFileLightboxController' => 'PhabricatorFileController', 'PhabricatorFileLinkView' => 'AphrontView', 'PhabricatorFileListController' => 'PhabricatorFileController', 'PhabricatorFileQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', diff --git a/src/applications/files/application/PhabricatorFilesApplication.php b/src/applications/files/application/PhabricatorFilesApplication.php index 5f3fb797c3..5733439fcf 100644 --- a/src/applications/files/application/PhabricatorFilesApplication.php +++ b/src/applications/files/application/PhabricatorFilesApplication.php @@ -76,6 +76,7 @@ final class PhabricatorFilesApplication extends PhabricatorApplication { 'dropupload/' => 'PhabricatorFileDropUploadController', 'compose/' => 'PhabricatorFileComposeController', 'comment/(?P[1-9]\d*)/' => 'PhabricatorFileCommentController', + 'thread/(?P[^/]+)/' => 'PhabricatorFileLightboxController', 'delete/(?P[1-9]\d*)/' => 'PhabricatorFileDeleteController', 'edit/(?P[1-9]\d*)/' => 'PhabricatorFileEditController', 'info/(?P[^/]+)/' => 'PhabricatorFileInfoController', diff --git a/src/applications/files/controller/PhabricatorFileLightboxController.php b/src/applications/files/controller/PhabricatorFileLightboxController.php new file mode 100644 index 0000000000..ca5576c6bd --- /dev/null +++ b/src/applications/files/controller/PhabricatorFileLightboxController.php @@ -0,0 +1,43 @@ +getViewer(); + $phid = $request->getURIData('phid'); + + $file = id(new PhabricatorFileQuery()) + ->setViewer($viewer) + ->withPHIDs(array($phid)) + ->executeOne(); + if (!$file) { + return new Aphront404Response(); + } + + $transactions = id(new PhabricatorFileTransactionQuery()) + ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)); + $timeline = $this->buildTransactionTimeline($file, $transactions); + + if ($timeline->isTimelineEmpty()) { + $timeline = phutil_tag( + 'div', + array( + 'class' => 'phui-comment-panel-empty', + ), + pht('No comments.')); + } + + require_celerity_resource('phui-comment-panel-css'); + $content = phutil_tag( + 'div', + array( + 'class' => 'phui-comment-panel', + ), + $timeline); + + return id(new AphrontAjaxResponse()) + ->setContent($content); + } + +} diff --git a/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php b/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php index 15b8771978..0fb2243d89 100644 --- a/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php +++ b/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php @@ -98,7 +98,7 @@ final class PhabricatorEmbedFileRemarkupRule PhabricatorObjectHandle $handle, array $options) { - require_celerity_resource('lightbox-attachment-css'); + require_celerity_resource('phui-lightbox-css'); $attrs = array(); $image_class = 'phabricator-remarkup-embed-image'; @@ -176,6 +176,7 @@ final class PhabricatorEmbedFileRemarkupRule 'uri' => $file->getBestURI(), 'dUri' => $file->getDownloadURI(), 'viewable' => true, + 'monogram' => $file->getMonogram(), ), ), $img); @@ -279,7 +280,8 @@ final class PhabricatorEmbedFileRemarkupRule ->setFileName($this->assertFlatText($options['name'])) ->setFileDownloadURI($file->getDownloadURI()) ->setFileViewURI($file->getBestURI()) - ->setFileViewable((bool)$options['viewable']); + ->setFileViewable((bool)$options['viewable']) + ->setFileMonogram($file->getMonogram()); } private function parseDimension($string) { diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionView.php index 6e27f8540b..5eaa5288de 100644 --- a/src/applications/transactions/view/PhabricatorApplicationTransactionView.php +++ b/src/applications/transactions/view/PhabricatorApplicationTransactionView.php @@ -233,6 +233,10 @@ class PhabricatorApplicationTransactionView extends AphrontView { return $view; } + public function isTimelineEmpty() { + return !count($this->buildEvents(true)); + } + protected function getOrBuildEngine() { if (!$this->engine) { $field = PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT; diff --git a/src/view/form/control/PhabricatorRemarkupControl.php b/src/view/form/control/PhabricatorRemarkupControl.php index a2fb7fc7a8..86bb416e90 100644 --- a/src/view/form/control/PhabricatorRemarkupControl.php +++ b/src/view/form/control/PhabricatorRemarkupControl.php @@ -29,7 +29,7 @@ final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { // We need to have this if previews render images, since Ajax can not // currently ship JS or CSS. - require_celerity_resource('lightbox-attachment-css'); + require_celerity_resource('phui-lightbox-css'); if (!$this->getDisabled()) { Javelin::initBehavior( diff --git a/src/view/layout/PhabricatorFileLinkView.php b/src/view/layout/PhabricatorFileLinkView.php index 8551b4c567..ab993b9b6d 100644 --- a/src/view/layout/PhabricatorFileLinkView.php +++ b/src/view/layout/PhabricatorFileLinkView.php @@ -7,12 +7,14 @@ final class PhabricatorFileLinkView extends AphrontView { private $fileViewURI; private $fileViewable; private $filePHID; + private $fileMonogram; private $customClass; public function setCustomClass($custom_class) { $this->customClass = $custom_class; return $this; } + public function getCustomClass() { return $this->customClass; } @@ -21,14 +23,25 @@ final class PhabricatorFileLinkView extends AphrontView { $this->filePHID = $file_phid; return $this; } + private function getFilePHID() { return $this->filePHID; } + public function setFileMonogram($monogram) { + $this->fileMonogram = $monogram; + return $this; + } + + private function getFileMonogram() { + return $this->fileMonogram; + } + public function setFileViewable($file_viewable) { $this->fileViewable = $file_viewable; return $this; } + private function getFileViewable() { return $this->fileViewable; } @@ -37,6 +50,7 @@ final class PhabricatorFileLinkView extends AphrontView { $this->fileViewURI = $file_view_uri; return $this; } + private function getFileViewURI() { return $this->fileViewURI; } @@ -45,6 +59,7 @@ final class PhabricatorFileLinkView extends AphrontView { $this->fileDownloadURI = $file_download_uri; return $this; } + private function getFileDownloadURI() { return $this->fileDownloadURI; } @@ -53,6 +68,7 @@ final class PhabricatorFileLinkView extends AphrontView { $this->fileName = $file_name; return $this; } + private function getFileName() { return $this->fileName; } @@ -64,12 +80,13 @@ final class PhabricatorFileLinkView extends AphrontView { 'uri' => $this->getFileViewURI(), 'dUri' => $this->getFileDownloadURI(), 'name' => $this->getFileName(), + 'monogram' => $this->getFileMonogram(), ); } public function render() { require_celerity_resource('phabricator-remarkup-css'); - require_celerity_resource('lightbox-attachment-css'); + require_celerity_resource('phui-lightbox-css'); $sigil = null; $meta = null; diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php index 242e2e2659..93d02b8b73 100644 --- a/src/view/page/PhabricatorStandardPageView.php +++ b/src/view/page/PhabricatorStandardPageView.php @@ -271,6 +271,9 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView $default_img_uri = celerity_get_resource_uri( 'rsrc/image/icon/fatcow/document_black.png'); + $icon = id(new PHUIIconView()) + ->setIcon('fa-download'); + $lightbox_id = celerity_generate_unique_node_id(); $download_form = phabricator_form( $user, array( @@ -281,12 +284,18 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView ), phutil_tag( 'button', - array('class' => 'button grey'), - pht('Download'))); + array( + 'class' => 'button grey has-icon', + ), + array( + $icon, + pht('Download'), + ))); Javelin::initBehavior( 'lightbox-attachments', array( + 'lightbox_id' => $lightbox_id, 'defaultImageUri' => $default_img_uri, 'downloadForm' => $download_form, )); diff --git a/webroot/rsrc/css/aphront/dialog-view.css b/webroot/rsrc/css/aphront/dialog-view.css index 5d9d2046dc..9cf56394df 100644 --- a/webroot/rsrc/css/aphront/dialog-view.css +++ b/webroot/rsrc/css/aphront/dialog-view.css @@ -108,6 +108,11 @@ opacity: 0.95; } +.jx-white-mask { + background: #fff; + opacity: 1; +} + .jx-date-mask { background: #292f33; opacity: 0.5; diff --git a/webroot/rsrc/css/phui/phui-comment-panel.css b/webroot/rsrc/css/phui/phui-comment-panel.css new file mode 100644 index 0000000000..7eacd59fd2 --- /dev/null +++ b/webroot/rsrc/css/phui/phui-comment-panel.css @@ -0,0 +1,60 @@ +/** + * @provides phui-comment-panel-css + * @requires phui-timeline-view-css + */ + +.phui-comment-panel .phui-timeline-view { + background: none; +} + +.phui-comment-panel .phui-comment-panel-empty { + margin: 16px; + padding: 12px; + border: 1px solid {$thinblueborder}; + background: {$lightbluebackground}; + text-align: center; + color: {$lightbluetext}; +} + +.phui-comment-panel .phui-timeline-view .phui-timeline-event-view { + margin: 0; +} + +.phui-comment-panel .phui-timeline-view .phui-timeline-image { + display: none; +} + +.phui-comment-panel .phui-timeline-view .phui-timeline-wedge { + display: none; +} + +.phui-comment-panel .phui-timeline-major-event .phui-timeline-group { + border: none; +} + +.phui-comment-panel .phui-timeline-major-event .phui-timeline-title { + background: none; + border: none; + padding: 0; + visibility: hidden; +} + +.phui-comment-panel .phui-timeline-major-event .phui-timeline-title a { + visibility: visible; +} + +.phui-comment-panel .phui-timeline-icon-fill, +.phui-comment-panel .phui-timeline-menu { + display: none; +} + +.phui-comment-panel .phui-timeline-major-event .phui-timeline-content { + border: none; +} + +.phui-comment-panel .phui-timeline-major-event .phui-timeline-content + .phui-timeline-core-content { + border: none; + padding: 4px 0; + background: transparent; +} diff --git a/webroot/rsrc/css/aphront/lightbox-attachment.css b/webroot/rsrc/css/phui/phui-lightbox.css similarity index 55% rename from webroot/rsrc/css/aphront/lightbox-attachment.css rename to webroot/rsrc/css/phui/phui-lightbox.css index 8f850e185c..e70cb4e9b6 100644 --- a/webroot/rsrc/css/aphront/lightbox-attachment.css +++ b/webroot/rsrc/css/phui/phui-lightbox.css @@ -1,5 +1,5 @@ /** - * @provides lightbox-attachment-css + * @provides phui-lightbox-css */ @@ -16,26 +16,52 @@ overflow-y: auto; } -.lightbox-attachment img { - max-width: calc(100% - 44px); - max-height: calc(100% - 44px); +.lightbox-attachment .lightbox-image-frame { position: absolute; top: 44px; right: 0; bottom: 0; left: 0; +} + +.lightbox-attachment.comment-panel-open .lightbox-image-frame { + right: 320px; +} + +.lightbox-attachment .lightbox-image-frame img { + max-width: calc(100% - 40px); + max-height: calc(100% - 24px); + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; margin: auto; } +.lightbox-comment-frame { + position: absolute; + top: -19999px; + bottom: -19999px; + opacity: 0; + transition: all 0.2s; +} + +.comment-panel-open .lightbox-comment-frame { + position: fixed; + top: 44px; + bottom: 0; + right: 0; + width: 320px; + overflow-y: auto; + background: #fff; + opacity: 1; +} + .jx-mask + .lightbox-attachment { background: {$lightgreybackground}; } -.lightbox-attachment .loading { - position: absolute; - top: -9999px; -} - .lightbox-attachment .attachment-name { width: 100%; line-height: 30px; @@ -52,20 +78,42 @@ padding: 0 20px; line-height: 44px; border-bottom: 1px solid {$thinblueborder}; + color: {$greytext}; } .lightbox-attachment .lightbox-status .lightbox-download { float: right; } +.lightbox-attachment .lightbox-status a { + color: #000; + margin-right: 4px; + font-size: {$biggerfontsize}; +} + +.lightbox-download button.has-icon { + padding-left: 28px; +} + .lightbox-attachment .lightbox-status .lightbox-download .lightbox-download-form { display: inline; } +.lightbox-attachment .lightbox-comment { + float: right; + margin: 9px 0 0 8px; + padding-left: 28px; +} + +.lightbox-attachment.comment-panel-open .lightbox-comment, +.lightbox-attachment.comment-panel-open .lightbox-comment .phui-icon-view { + color: {$sky}; +} + .lightbox-attachment .lightbox-close { float: right; - margin: 9px 0 0px 8px; + margin: 9px 0 0 8px; } .lightbox-attachment .lightbox-left { @@ -94,6 +142,10 @@ width: 21px; } +.lightbox-attachment.comment-panel-open .lightbox-right .phui-icon-view { + right: 322px; +} + .lightbox-attachment .lightbox-right .phui-icon-view { font-size: 40px; } diff --git a/webroot/rsrc/js/core/behavior-lightbox-attachments.js b/webroot/rsrc/js/core/behavior-lightbox-attachments.js index 40022b1883..e3d863561c 100644 --- a/webroot/rsrc/js/core/behavior-lightbox-attachments.js +++ b/webroot/rsrc/js/core/behavior-lightbox-attachments.js @@ -14,7 +14,34 @@ JX.behavior('lightbox-attachments', function (config) { var lightbox = null; var prev = null; var next = null; + var shown = false; var downloadForm = JX.$H(config.downloadForm).getFragment().firstChild; + var lightbox_id = config.lightbox_id; + + function _toggleComment(e) { + e.kill(); + shown = !shown; + JX.DOM.alterClass(JX.$(lightbox_id), 'comment-panel-open', shown); + } + + function markCommentsLoading(loading) { + var frame = JX.$('lightbox-comment-frame'); + JX.DOM.alterClass(frame, 'loading', loading); + } + + function onLoadCommentsResponse(r) { + var frame = JX.$('lightbox-comment-frame'); + JX.DOM.setContent(frame, JX.$H(r)); + markCommentsLoading(false); + } + + function loadComments(phid) { + markCommentsLoading(true); + var uri = '/file/thread/' + phid + '/'; + new JX.Workflow(uri) + .setHandler(onLoadCommentsResponse) + .start(); + } function loadLightBox(e) { if (!e.isNormalClick()) { @@ -61,10 +88,13 @@ JX.behavior('lightbox-attachments', function (config) { } else { img_uri = config.defaultImageUri; extra_status = ' Image may not be representative of actual attachment.'; - name_element = JX.$N('div', - { className : 'attachment-name' }, - target_data.name - ); + name_element = + JX.$N('div', + { + className : 'attachment-name' + }, + target_data.name + ); } var alt_name = ''; @@ -72,44 +102,87 @@ JX.behavior('lightbox-attachments', function (config) { alt_name = target_data.name; } - var img = JX.$N('img', - { - className : 'loading', - alt : alt_name - } - ); + var img = + JX.$N('img', + { + className : 'loading', + alt : alt_name + } + ); - lightbox = JX.$N('div', - { - className : 'lightbox-attachment', - sigil: 'lightbox-attachment' - }, - img - ); + var imgFrame = + JX.$N('div', + { + className : 'lightbox-image-frame', + }, + img + ); - var statusSpan = JX.$N('span', - { - className: 'lightbox-status-txt' - }, - 'Image '+current+' of '+total+'.'+extra_status - ); + var commentFrame = + JX.$N('div', + { + className : 'lightbox-comment-frame', + id : 'lightbox-comment-frame' + } + ); - var downloadSpan = JX.$N('span', - { - className : 'lightbox-download' - }); - var closeButton = JX.$N('a', - { - className : 'lightbox-close button grey', - href : '#' - }, - 'Close'); - var statusHTML = JX.$N('div', - { - className : 'lightbox-status' - }, - [statusSpan, closeButton, downloadSpan] - ); + var commentClass = (shown) ? 'comment-panel-open' : ''; + lightbox = + JX.$N('div', + { + className : 'lightbox-attachment ' + commentClass, + sigil : 'lightbox-attachment', + id : lightbox_id + }, + [imgFrame, commentFrame] + ); + + var monogram = JX.$N('strong', {}, target_data.monogram); + var m_url = JX.$N('a', { href : '/' + target_data.monogram }, monogram); + var statusSpan = + JX.$N('span', + { + className: 'lightbox-status-txt' + }, + [ + m_url, + ' Image ' + current + ' of ' + total + '.' + extra_status + ] + ); + + var downloadSpan = + JX.$N('span', + { + className : 'lightbox-download' + } + ); + + var commentIcon = new JX.PHUIXIconView() + .setIcon('fa-comment-o') + .getNode(); + var commentButton = + JX.$N('a', + { + className : 'lightbox-comment button grey has-icon', + href : '#', + sigil : 'lightbox-comment' + }, + [commentIcon, 'Comment'] + ); + var closeButton = + JX.$N('a', + { + className : 'lightbox-close button grey', + href : '#' + }, + 'Close'); + var statusHTML = + JX.$N('div', + { + className : 'lightbox-status' + }, + [statusSpan, closeButton, commentButton, downloadSpan] + ); JX.DOM.appendContent(lightbox, statusHTML); JX.DOM.appendContent(lightbox, name_element); JX.DOM.listen(closeButton, 'click', null, closeLightBox); @@ -120,12 +193,14 @@ JX.behavior('lightbox-attachments', function (config) { .setIcon('fa-angle-right') .setColor('lightgreytext') .getNode(); - leftIcon = JX.$N('a', - { - className : 'lightbox-right', - href : '#' - }, - r_icon); + leftIcon = + JX.$N('a', + { + className : 'lightbox-right', + href : '#' + }, + r_icon + ); JX.DOM.listen(leftIcon, 'click', null, @@ -139,12 +214,14 @@ JX.behavior('lightbox-attachments', function (config) { .setIcon('fa-angle-left') .setColor('lightgreytext') .getNode(); - rightIcon = JX.$N('a', - { - className : 'lightbox-left', - href : '#' - }, - l_icon); + rightIcon = + JX.$N('a', + { + className : 'lightbox-left', + href : '#' + }, + l_icon + ); JX.DOM.listen(rightIcon, 'click', null, @@ -168,6 +245,7 @@ JX.behavior('lightbox-attachments', function (config) { }; img.src = img_uri; + loadComments(target_data.phid); } // TODO - make this work with KeyboardShortcut, which means @@ -252,4 +330,9 @@ JX.behavior('lightbox-attachments', function (config) { e.kill(); }); + JX.Stratcom.listen( + 'click', + 'lightbox-comment', + _toggleComment); + });