From 0acdf256fc9d5d3130eb19943c15791200f2be8b Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Mon, 13 Apr 2015 15:24:48 -0700 Subject: [PATCH] Conpherence - get #anchor links to messages working Summary: Ref T7757. Oddities include: - not working in column view, since the generic anchor technology conflicts once you navigate to a page with a transaction timeline view - not working if you are linking to a message not included in initial load Remaining work is addressing these oddities. - make column view timestamp link to full conpherence correctly? - make back end load from hyperlinked transaction forward? or do it more like application transactions and have the client keep requesting stuff until it gets it? Open to suggestions! :D Test Plan: played around in conpherence full and stuff looked okay. noted no changes as intended in column view. Reviewers: epriestley, chad Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7757 Differential Revision: https://secure.phabricator.com/D12402 --- resources/celerity/map.php | 70 +++++++++---------- .../view/ConpherenceTransactionView.php | 26 ++++++- .../layout/PhabricatorTransactionView.php | 5 +- .../conpherence/durable-column.css | 7 +- .../application/conpherence/message-pane.css | 20 ++++++ .../application/conpherence/behavior-menu.js | 14 +++- .../conpherence/behavior-widget-pane.js | 1 - 7 files changed, 99 insertions(+), 44 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index e9bfc70d35..bd0d09fa62 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -44,9 +44,9 @@ return array( 'rsrc/css/application/config/config-welcome.css' => '6abd79be', 'rsrc/css/application/config/setup-issue.css' => '22270af2', 'rsrc/css/application/config/unhandled-exception.css' => '37d4f9a2', - 'rsrc/css/application/conpherence/durable-column.css' => 'f0c208ac', + 'rsrc/css/application/conpherence/durable-column.css' => '16051a19', 'rsrc/css/application/conpherence/menu.css' => 'f389e048', - 'rsrc/css/application/conpherence/message-pane.css' => 'e44b667b', + 'rsrc/css/application/conpherence/message-pane.css' => 'e978e4ae', 'rsrc/css/application/conpherence/notification.css' => '72178795', 'rsrc/css/application/conpherence/update.css' => '1099a660', 'rsrc/css/application/conpherence/widget-pane.css' => 'a9082fd0', @@ -356,10 +356,10 @@ return array( 'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de', 'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '0a5192c4', 'rsrc/js/application/conpherence/behavior-durable-column.js' => '7ffa744f', - 'rsrc/js/application/conpherence/behavior-menu.js' => 'e5826953', + 'rsrc/js/application/conpherence/behavior-menu.js' => '13d94a68', 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', - 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '31b18ee7', + 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '93568464', 'rsrc/js/application/countdown/timer.js' => 'e4cc26b3', 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '469c0d9e', 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => '82439934', @@ -515,9 +515,9 @@ return array( 'changeset-view-manager' => '58562350', 'config-options-css' => '7fedf08b', 'config-welcome-css' => '6abd79be', - 'conpherence-durable-column-view' => 'f0c208ac', + 'conpherence-durable-column-view' => '16051a19', 'conpherence-menu-css' => 'f389e048', - 'conpherence-message-pane-css' => 'e44b667b', + 'conpherence-message-pane-css' => 'e978e4ae', 'conpherence-notification-css' => '72178795', 'conpherence-thread-manager' => '0a5192c4', 'conpherence-update-css' => '1099a660', @@ -559,9 +559,9 @@ return array( 'javelin-behavior-boards-dropdown' => '0ec56e1d', 'javelin-behavior-choose-control' => '6153c708', 'javelin-behavior-config-reorder-fields' => '14a827de', - 'javelin-behavior-conpherence-menu' => 'e5826953', + 'javelin-behavior-conpherence-menu' => '13d94a68', 'javelin-behavior-conpherence-pontificate' => '21ba5861', - 'javelin-behavior-conpherence-widget-pane' => '31b18ee7', + 'javelin-behavior-conpherence-widget-pane' => '93568464', 'javelin-behavior-countdown-timer' => 'e4cc26b3', 'javelin-behavior-dark-console' => '08883e8b', 'javelin-behavior-dashboard-async-panel' => '469c0d9e', @@ -909,6 +909,20 @@ return array( 'javelin-uri', 'phabricator-textareautils', ), + '13d94a68' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-util', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-behavior-device', + 'javelin-history', + 'javelin-vector', + 'javelin-scrollbar', + 'phabricator-title', + 'phabricator-shaped-request', + 'conpherence-thread-manager', + ), '1499a8cb' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1043,19 +1057,6 @@ return array( 'javelin-install', 'javelin-typeahead-source', ), - '31b18ee7' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-util', - 'phabricator-notification', - 'javelin-behavior-device', - 'phuix-dropdown-menu', - 'phuix-action-list-view', - 'phuix-action-view', - 'conpherence-thread-manager', - ), '331b1611' => array( 'javelin-install', ), @@ -1551,6 +1552,19 @@ return array( 'javelin-dom', 'javelin-stratcom', ), + 93568464 => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-util', + 'phabricator-notification', + 'javelin-behavior-device', + 'phuix-dropdown-menu', + 'phuix-action-list-view', + 'phuix-action-view', + 'conpherence-thread-manager', + ), '9414ff18' => array( 'javelin-behavior', 'javelin-resource', @@ -1874,20 +1888,6 @@ return array( 'javelin-workflow', 'javelin-magical-init', ), - 'e5826953' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-behavior-device', - 'javelin-history', - 'javelin-vector', - 'javelin-scrollbar', - 'phabricator-title', - 'phabricator-shaped-request', - 'conpherence-thread-manager', - ), 'e58bf807' => array( 'javelin-behavior', 'javelin-util', diff --git a/src/applications/conpherence/view/ConpherenceTransactionView.php b/src/applications/conpherence/view/ConpherenceTransactionView.php index af1a4a76b1..09653ac242 100644 --- a/src/applications/conpherence/view/ConpherenceTransactionView.php +++ b/src/applications/conpherence/view/ConpherenceTransactionView.php @@ -5,6 +5,7 @@ final class ConpherenceTransactionView extends AphrontView { private $conpherenceTransaction; private $handles; private $markupEngine; + private $renderAnchors = true; private $showImages = true; private $showContentSource = true; @@ -50,6 +51,15 @@ final class ConpherenceTransactionView extends AphrontView { return $this->showContentSource; } + public function setRenderAnchors($bool) { + $this->renderAnchors = $bool; + return $this; + } + + private function getRenderAnchors() { + return $this->renderAnchors; + } + public function render() { $user = $this->getUser(); $transaction = $this->getConpherenceTransaction(); @@ -78,9 +88,17 @@ final class ConpherenceTransactionView extends AphrontView { $transaction->setHandles($handles); $author = $handles[$transaction->getAuthorPHID()]; $transaction_view = id(new PhabricatorTransactionView()) - ->setUser($user) - ->setEpoch($transaction->getDateCreated()) - ->setTimeOnly(true); + ->setUser($user); + if ($this->getRenderAnchors()) { + $transaction_view + ->setAnchor( + $transaction->getID(), + phabricator_time($transaction->getDateCreated(), $user)); + } else { + $transaction_view + ->setEpoch($transaction->getDateCreated()) + ->setTimeOnly(true); + } if ($this->getShowContentSource()) { $transaction_view->setContentSource($transaction->getContentSource()); } @@ -169,6 +187,7 @@ final class ConpherenceTransactionView extends AphrontView { ->setHandles($handles) ->setShowImages($full_display) ->setShowContentSource($full_display) + ->setRenderAnchors($full_display) ->setMarkupEngine($engine); foreach ($transactions as $transaction) { if ($previous_transaction) { @@ -192,6 +211,7 @@ final class ConpherenceTransactionView extends AphrontView { ->setConpherenceTransaction($transaction) ->setHandles($handles) ->setMarkupEngine($engine) + ->setRenderAnchors($full_display) ->setShowImages($full_display) ->setShowContentSource($full_display) ->render(); diff --git a/src/view/layout/PhabricatorTransactionView.php b/src/view/layout/PhabricatorTransactionView.php index 9b3b4bbf49..398cafe215 100644 --- a/src/view/layout/PhabricatorTransactionView.php +++ b/src/view/layout/PhabricatorTransactionView.php @@ -121,7 +121,10 @@ final class PhabricatorTransactionView extends AphrontView { $anchor, phutil_tag( 'a', - array('href' => '#'.$this->anchorName), + array( + 'href' => '#'.$this->anchorName, + 'class' => 'anchor-link', + ), $this->anchorText)); } diff --git a/webroot/rsrc/css/application/conpherence/durable-column.css b/webroot/rsrc/css/application/conpherence/durable-column.css index f482ef170a..9f36076b89 100644 --- a/webroot/rsrc/css/application/conpherence/durable-column.css +++ b/webroot/rsrc/css/application/conpherence/durable-column.css @@ -198,12 +198,17 @@ } .conpherence-durable-column-transactions .phabricator-transaction-detail -.phabricator-transaction-header .phabricator-transaction-info { +.phabricator-transaction-header .phabricator-transaction-info, +.phabricator-transaction-header .anchor-link { color: {$lightbluetext}; float: none; font-size: 12px; } +.phabricator-transaction-header .anchor-link { + font-weight: normal; +} + .conpherence-durable-column-transactions .phabricator-transaction-detail .phabricator-transaction-header .phui-link-person { margin: 0 8px 0 0; diff --git a/webroot/rsrc/css/application/conpherence/message-pane.css b/webroot/rsrc/css/application/conpherence/message-pane.css index 0a04bac204..eca76a7121 100644 --- a/webroot/rsrc/css/application/conpherence/message-pane.css +++ b/webroot/rsrc/css/application/conpherence/message-pane.css @@ -151,6 +151,21 @@ margin: 0 10px 0 0; } +.conpherence-message-pane .conpherence-comment.anchor-target, +.conpherence-message-pane .conpherence-edited.anchor-target { + background: #fdf5d4; +} + +.conpherence-message-pane .conpherence-comment.anchor-target { + margin: 4px 8px 4px 8px; + padding: 2px 4px 2px 4px; +} + +.conpherence-message-pane .conpherence-edited.anchor-target { + margin: 0px 8px 0px 8px; + padding: 0px 4px 0px 4px; +} + .conpherence-message-pane .phabricator-transaction-detail { border-width: 0; margin-left: 45px; @@ -220,6 +235,7 @@ } .conpherence-message-pane .phabricator-transaction-info, +.conpherence-message-pane .anchor-link, .conpherence-message-pane .phabricator-content-source-view { color: {$lightbluetext}; line-height: 16px; @@ -228,10 +244,14 @@ .conpherence-message-pane .phabricator-transaction-header, .conpherence-message-pane .phabricator-transaction-info, +.conpherence-message-pane .anchor-link, .conpherence-message-pane .phabricator-transaction-content { background: none; padding: 0; } +.conpherence-message-pane .anchor-link { + font-weight: normal; +} .conpherence-message-pane .phabricator-transaction-content { padding: 2px 0 8px 0; diff --git a/webroot/rsrc/js/application/conpherence/behavior-menu.js b/webroot/rsrc/js/application/conpherence/behavior-menu.js index 1bf8b2d964..f9a47bbb03 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-menu.js +++ b/webroot/rsrc/js/application/conpherence/behavior-menu.js @@ -52,7 +52,7 @@ JX.behavior('conpherence-menu', function(config) { var messages_root = JX.DOM.find(root, 'div', 'conpherence-message-pane'); var messages = JX.DOM.find(messages_root, 'div', 'conpherence-messages'); JX.DOM.appendContent(messages, JX.$H(r.transactions)); - scrollbar.scrollTo(messages.scrollHeight); + _scrollMessageWindow(); }); threadManager.setWillSendMessageCallback(function () { var root = JX.DOM.find(document, 'div', 'conpherence-layout'); @@ -74,7 +74,7 @@ JX.behavior('conpherence-menu', function(config) { // Ignore; maybe no files widget } JX.DOM.appendContent(messages, JX.$H(r.transactions)); - scrollbar.scrollTo(messages.scrollHeight); + _scrollMessageWindow(); if (fileWidget) { JX.DOM.setContent( @@ -321,9 +321,17 @@ JX.behavior('conpherence-menu', function(config) { buildDeviceWidgetSelector : build_device_widget_selector }); } + var _firstScroll = true; function _scrollMessageWindow() { var root = JX.DOM.find(document, 'div', 'conpherence-layout'); var messages_root = JX.DOM.find(root, 'div', 'conpherence-messages'); + if (_firstScroll) { + _firstScroll = false; + // let the standard #anchor tech take over + if (window.location.hash) { + return; + } + } scrollbar.scrollTo(messages_root.scrollHeight); } function _focusTextarea() { @@ -377,7 +385,7 @@ JX.behavior('conpherence-menu', function(config) { new JX.Workflow.newFromForm(form, data) .setHandler(JX.bind(this, function(r) { JX.DOM.appendContent(messages, JX.$H(r.transactions)); - scrollbar.scrollTo(messages.scrollHeight); + _scrollMessageWindow(); JX.DOM.setContent( header, diff --git a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js index e067792fcb..227db56907 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js +++ b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js @@ -210,7 +210,6 @@ JX.behavior('conpherence-widget-pane', function(config) { // as a widget, but shown always on the desktop if (widget == 'conpherence-message-pane') { JX.$(widget).style.display = 'block'; - JX.Stratcom.invoke('conpherence-redraw-thread', null, {}); } continue; }