From 39afb3fedb72312d22d076a589c609dbb93a3b68 Mon Sep 17 00:00:00 2001 From: Bryan Cuccioli Date: Mon, 4 Feb 2013 09:03:19 -0800 Subject: [PATCH 01/13] Suggest STRICT_ALL_TABLES during setup. Improve dev-mode comments. Summary: Suggest the MySQL mode STRICT_ALL_TABLES during setup if it is not set. Small improvement to the phabricator.developer-mode comments. Test Plan: Set the global sql_mode to include or exclude STRICT_ALL_TABLES and check for desired behavior. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D4803 --- conf/default.conf.php | 3 ++- .../config/check/PhabricatorSetupCheckDatabase.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/conf/default.conf.php b/conf/default.conf.php index a9e4cff5a1..26f76dd3ce 100644 --- a/conf/default.conf.php +++ b/conf/default.conf.php @@ -801,7 +801,8 @@ return array( // Show stack traces when unhandled exceptions occur, force reloading of // static resources (skipping the cache), show an error callout if a page // generated PHP errors, warnings, or notices, force disk reads when - // reloading. This option should not be enabled in production. + // reloading, and generally make development easier. This option should not + // be enabled in production. 'phabricator.developer-mode' => false, // When users write comments which have URIs, they'll be automatically linked diff --git a/src/applications/config/check/PhabricatorSetupCheckDatabase.php b/src/applications/config/check/PhabricatorSetupCheckDatabase.php index adef6a7cc1..67ce6bc94c 100644 --- a/src/applications/config/check/PhabricatorSetupCheckDatabase.php +++ b/src/applications/config/check/PhabricatorSetupCheckDatabase.php @@ -65,6 +65,20 @@ final class PhabricatorSetupCheckDatabase extends PhabricatorSetupCheck { return; } + if (PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) { + $mode_string = queryfx_one($conn_raw, "SELECT @@sql_mode"); + $modes = explode(',', $mode_string['@@sql_mode']); + if (!in_array('STRICT_ALL_TABLES', $modes)) { + $message = pht( + "The global sql_mode is not set to 'STRICT_ALL_TABLES'. It is ". + "recommended that you set this mode while developing Phabricator."); + + $this->newIssue('mysql.mode') + ->setName(pht('MySQL STRICT_ALL_TABLES mode not set.')) + ->setMessage($message); + } + } + $namespace = PhabricatorEnv::getEnvConfig('storage.default-namespace'); $databases = queryfx_all($conn_raw, 'SHOW DATABASES'); From ccb206e984d1650fcad8b9c2376f4da409d58b9e Mon Sep 17 00:00:00 2001 From: Debarghya Das Date: Mon, 4 Feb 2013 09:54:01 -0800 Subject: [PATCH 02/13] Added a Disable Macros function that can be called in some contexts where Macros are unsuitable Summary: Semi Fixed T2397 Test Plan: Can disable the meme button on manually toggling the class variable. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T2397 Differential Revision: https://secure.phabricator.com/D4781 --- .../blog/PhameBlogEditController.php | 3 ++- .../post/PhamePostEditController.php | 1 + .../control/PhabricatorRemarkupControl.php | 25 +++++++++++-------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/applications/phame/controller/blog/PhameBlogEditController.php b/src/applications/phame/controller/blog/PhameBlogEditController.php index d043b147a2..6a9f952726 100644 --- a/src/applications/phame/controller/blog/PhameBlogEditController.php +++ b/src/applications/phame/controller/blog/PhameBlogEditController.php @@ -122,7 +122,8 @@ final class PhameBlogEditController ->setName('description') ->setValue($blog->getDescription()) ->setID('blog-description') - ->setUser($user)) + ->setUser($user) + ->setDisableMacros(true)) ->appendChild( id(new AphrontFormPolicyControl()) ->setUser($user) diff --git a/src/applications/phame/controller/post/PhamePostEditController.php b/src/applications/phame/controller/post/PhamePostEditController.php index 2f16595716..20217edc51 100644 --- a/src/applications/phame/controller/post/PhamePostEditController.php +++ b/src/applications/phame/controller/post/PhamePostEditController.php @@ -133,6 +133,7 @@ final class PhamePostEditController ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL) ->setID('post-body') ->setUser($user) + ->setDisableMacros(true) ) ->appendChild( id(new AphrontFormSelectControl()) diff --git a/src/view/form/control/PhabricatorRemarkupControl.php b/src/view/form/control/PhabricatorRemarkupControl.php index 5198c0cf8d..5520a7f5fe 100644 --- a/src/view/form/control/PhabricatorRemarkupControl.php +++ b/src/view/form/control/PhabricatorRemarkupControl.php @@ -1,7 +1,11 @@ disableMacro = $disable; + return $this; + } protected function renderInput() { $id = $this->getID(); if (!$id) { @@ -48,20 +52,22 @@ final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { ), 'table' => array( 'tip' => pht('Table'), - ), - array( + ) + ); + if (!$this->disableMacro and function_exists('imagettftext')) { + $actions[] = array( 'spacer' => true, - ), - 'meme' => array( + ); + $actions['meme'] = array( 'tip' => pht('Meme'), - ), - 'help' => array( + ); + } + $actions['help'] = array( 'tip' => pht('Help'), 'align' => 'right', 'href' => PhabricatorEnv::getDoclink( 'article/Remarkup_Reference.html'), - ), - ); + ); $buttons = array(); foreach ($actions as $action => $spec) { @@ -74,7 +80,6 @@ final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { ''); continue; } - $classes = array(); $classes[] = 'remarkup-assist-button'; if (idx($spec, 'align') == 'right') { From 8c99938aad550fb5fd3e9464cb466735e1aba13e Mon Sep 17 00:00:00 2001 From: vrana Date: Fri, 1 Feb 2013 16:48:10 -0800 Subject: [PATCH 03/13] Convert revision unsubscribers to edges Test Plan: Ran the migration on a single revision, verified DB, called `loadUnsubscribedPHIDs()`. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D4786 --- .../patches/20130201.revisionunsubscribed.php | 33 +++++++++++++++++++ .../patches/20130201.revisionunsubscribed.sql | 2 ++ .../editor/DifferentialRevisionEditor.php | 22 +++++-------- .../storage/DifferentialRevision.php | 7 ++-- .../patch/PhabricatorBuiltinPatchList.php | 8 +++++ 5 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 resources/sql/patches/20130201.revisionunsubscribed.php create mode 100644 resources/sql/patches/20130201.revisionunsubscribed.sql diff --git a/resources/sql/patches/20130201.revisionunsubscribed.php b/resources/sql/patches/20130201.revisionunsubscribed.php new file mode 100644 index 0000000000..b15379893b --- /dev/null +++ b/resources/sql/patches/20130201.revisionunsubscribed.php @@ -0,0 +1,33 @@ +openTransaction(); + +// We couldn't use new LiskMigrationIterator($table) because the $unsubscribed +// property gets deleted. +$revs = queryfx_all( + $table->establishConnection('w'), + 'SELECT id, phid, unsubscribed FROM differential_revision'); + +foreach ($revs as $rev) { + echo "."; + + $unsubscribed = json_decode($rev['unsubscribed']); + if (!$unsubscribed) { + continue; + } + + $editor = new PhabricatorEdgeEditor(); + $editor->setSuppressEvents(true); + foreach ($unsubscribed as $user_phid => $_) { + $editor->addEdge( + $rev['phid'], + PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER, + $user_phid); + } + $editor->save(); +} + +$table->saveTransaction(); +echo "Done.\n"; diff --git a/resources/sql/patches/20130201.revisionunsubscribed.sql b/resources/sql/patches/20130201.revisionunsubscribed.sql new file mode 100644 index 0000000000..51f09cc104 --- /dev/null +++ b/resources/sql/patches/20130201.revisionunsubscribed.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_differential.differential_revision + DROP unsubscribed; diff --git a/src/applications/differential/editor/DifferentialRevisionEditor.php b/src/applications/differential/editor/DifferentialRevisionEditor.php index f347cd3b1c..d7c035637a 100644 --- a/src/applications/differential/editor/DifferentialRevisionEditor.php +++ b/src/applications/differential/editor/DifferentialRevisionEditor.php @@ -238,7 +238,7 @@ final class DifferentialRevisionEditor extends PhabricatorEditor { $diff); $adapter->setExplicitCCs($new['ccs']); $adapter->setExplicitReviewers($new['rev']); - $adapter->setForbiddenCCs($revision->getUnsubscribedPHIDs()); + $adapter->setForbiddenCCs($revision->loadUnsubscribedPHIDs()); $xscript = HeraldEngine::loadAndApplyRules($adapter); $xscript_uri = '/herald/transcript/'.$xscript->getID().'/'; @@ -500,12 +500,10 @@ final class DifferentialRevisionEditor extends PhabricatorEditor { self::addCC($revision, $phid, $reason); - $unsubscribed = $revision->getUnsubscribed(); - if (isset($unsubscribed[$phid])) { - unset($unsubscribed[$phid]); - $revision->setUnsubscribed($unsubscribed); - $revision->save(); - } + $type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER; + id(new PhabricatorEdgeEditor()) + ->removeEdge($revision->getPHID(), $type, $phid) + ->save(); } public static function removeCCAndUpdateRevision( @@ -515,12 +513,10 @@ final class DifferentialRevisionEditor extends PhabricatorEditor { self::removeCC($revision, $phid, $reason); - $unsubscribed = $revision->getUnsubscribed(); - if (empty($unsubscribed[$phid])) { - $unsubscribed[$phid] = true; - $revision->setUnsubscribed($unsubscribed); - $revision->save(); - } + $type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER; + id(new PhabricatorEdgeEditor()) + ->addEdge($revision->getPHID(), $type, $phid) + ->save(); } public static function addCC( diff --git a/src/applications/differential/storage/DifferentialRevision.php b/src/applications/differential/storage/DifferentialRevision.php index b34e5d8afe..b07f1beb29 100644 --- a/src/applications/differential/storage/DifferentialRevision.php +++ b/src/applications/differential/storage/DifferentialRevision.php @@ -17,7 +17,6 @@ final class DifferentialRevision extends DifferentialDAO { protected $lineCount; protected $attached = array(); - protected $unsubscribed = array(); protected $mailKey; protected $branchName; @@ -264,8 +263,10 @@ final class DifferentialRevision extends DifferentialDAO { return idx($this->relationships, $relation, array()); } - public function getUnsubscribedPHIDs() { - return array_keys($this->getUnsubscribed()); + public function loadUnsubscribedPHIDs() { + return PhabricatorEdgeQuery::loadDestinationPHIDs( + $this->phid, + PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER); } public function getPrimaryReviewer() { diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php index 9c1dee01f2..71dbe66291 100644 --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -1097,6 +1097,14 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList { 'type' => 'sql', 'name' => $this->getPatchPath('20130127.altheraldtranscript.sql'), ), + '20130201.revisionunsubscribed.php' => array( + 'type' => 'php', + 'name' => $this->getPatchPath('20130201.revisionunsubscribed.php'), + ), + '20130201.revisionunsubscribed.sql' => array( + 'type' => 'sql', + 'name' => $this->getPatchPath('20130201.revisionunsubscribed.sql'), + ), ); } From 34c51a61b55db778533f0ce63961ad83c50dc300 Mon Sep 17 00:00:00 2001 From: vrana Date: Fri, 1 Feb 2013 17:46:57 -0800 Subject: [PATCH 04/13] Delete preference for Diffusion symbols Summary: We are doing a better job in 1) of D3069#3 and 2) is just dumb. Let's see if someone notices this change. Test Plan: /settings/panel/display/ Reviewers: nh, epriestley Reviewed By: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D4789 --- .../view/DifferentialChangesetListView.php | 7 +------ .../controller/DiffusionBrowseFileController.php | 5 +---- ...PhabricatorSettingsPanelDisplayPreferences.php | 15 --------------- .../storage/PhabricatorUserPreferences.php | 1 - 4 files changed, 2 insertions(+), 26 deletions(-) diff --git a/src/applications/differential/view/DifferentialChangesetListView.php b/src/applications/differential/view/DifferentialChangesetListView.php index b180412254..43f33572a8 100644 --- a/src/applications/differential/view/DifferentialChangesetListView.php +++ b/src/applications/differential/view/DifferentialChangesetListView.php @@ -127,14 +127,9 @@ final class DifferentialChangesetListView extends AphrontView { $ref, $changeset); - $prefs = $this->user->loadPreferences(); - $pref_symbols = $prefs->getPreference( - PhabricatorUserPreferences::PREFERENCE_DIFFUSION_SYMBOLS); $detail->setChangeset($changeset); $detail->addButton($view_options); - if ($pref_symbols != 'disabled') { - $detail->setSymbolIndex(idx($this->symbolIndexes, $key)); - } + $detail->setSymbolIndex(idx($this->symbolIndexes, $key)); $detail->setVsChangesetID(idx($this->vsMap, $changeset->getID())); $detail->setEditable(true); diff --git a/src/applications/diffusion/controller/DiffusionBrowseFileController.php b/src/applications/diffusion/controller/DiffusionBrowseFileController.php index ac1e0abb80..2bcd13e008 100644 --- a/src/applications/diffusion/controller/DiffusionBrowseFileController.php +++ b/src/applications/diffusion/controller/DiffusionBrowseFileController.php @@ -251,10 +251,7 @@ final class DiffusionBrowseFileController extends DiffusionController { $lang = last(explode('.', $drequest->getPath())); - $prefs = $this->getRequest()->getUser()->loadPreferences(); - $pref_symbols = $prefs->getPreference( - PhabricatorUserPreferences::PREFERENCE_DIFFUSION_SYMBOLS); - if (isset($langs[$lang]) && $pref_symbols != 'disabled') { + if (isset($langs[$lang])) { Javelin::initBehavior( 'repository-crossreference', array( diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php b/src/applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php index 64195bd14d..d301775d21 100644 --- a/src/applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php +++ b/src/applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php @@ -24,8 +24,6 @@ final class PhabricatorSettingsPanelDisplayPreferences $pref_editor = PhabricatorUserPreferences::PREFERENCE_EDITOR; $pref_multiedit = PhabricatorUserPreferences::PREFERENCE_MULTIEDIT; $pref_titles = PhabricatorUserPreferences::PREFERENCE_TITLES; - $pref_symbols = - PhabricatorUserPreferences::PREFERENCE_DIFFUSION_SYMBOLS; $pref_monospaced_textareas = PhabricatorUserPreferences::PREFERENCE_MONOSPACED_TEXTAREAS; @@ -40,9 +38,6 @@ final class PhabricatorSettingsPanelDisplayPreferences $preferences->setPreference( $pref_multiedit, $request->getStr($pref_multiedit)); - $preferences->setPreference( - $pref_symbols, - $request->getStr($pref_symbols)); $preferences->setPreference($pref_monospaced, $monospaced); $preferences->setPreference( $pref_monospaced_textareas, @@ -74,7 +69,6 @@ EXAMPLE; $font_default = PhabricatorEnv::getEnvConfig('style.monospace'); $font_default = phutil_escape_html($font_default); - $pref_symbols_value = $preferences->getPreference($pref_symbols); $pref_monospaced_textareas_value = $preferences ->getPreference($pref_monospaced_textareas); if (!$pref_monospaced_textareas_value) { @@ -132,15 +126,6 @@ EXAMPLE; '
'.
           phutil_escape_html($example_string).
           '
')) - ->appendChild( - id(new AphrontFormRadioButtonControl()) - ->setLabel('Symbol Links') - ->setName($pref_symbols) - ->setValue($pref_symbols_value ? $pref_symbols_value : 'enabled') - ->addButton('enabled', 'Enabled (default)', - 'Use this setting to disable linking symbol names in Differential '. - 'and Diffusion to their definitions. This is enabled by default.') - ->addButton('disabled', 'Disabled', null)) ->appendChild( id(new AphrontFormRadioButtonControl()) ->setLabel('Monospaced Textareas') diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php index 4338e1ef61..e5910cf833 100644 --- a/src/applications/settings/storage/PhabricatorUserPreferences.php +++ b/src/applications/settings/storage/PhabricatorUserPreferences.php @@ -18,7 +18,6 @@ final class PhabricatorUserPreferences extends PhabricatorUserDAO { const PREFERENCE_SEARCH_SHORTCUT = 'search-shortcut'; const PREFERENCE_DIFFUSION_VIEW = 'diffusion-view'; - const PREFERENCE_DIFFUSION_SYMBOLS = 'diffusion-symbols'; const PREFERENCE_NAV_WIDTH = 'nav-width'; const PREFERENCE_APP_TILES = 'app-tiles'; From 22d5eee82ab9cf1063b3590b12031870510eff8f Mon Sep 17 00:00:00 2001 From: Brennan Taylor Date: Mon, 4 Feb 2013 12:43:06 -0800 Subject: [PATCH 05/13] Unsquish "No File Chosen" text on image selection forms Summary: Remove css class that was setting static width Test Plan: Loaded user profile edit page, stretched browser around, saw that the text was happy Reviewers: epriestley, btrahan Reviewed By: btrahan CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D4806 --- src/__celerity_resource_map__.php | 133 +++++++++--------- .../form/control/AphrontFormImageControl.php | 1 - webroot/rsrc/css/aphront/form-view.css | 4 - 3 files changed, 68 insertions(+), 70 deletions(-) diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index e75f779965..3df75ec35a 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -639,7 +639,7 @@ celerity_register_resource_map(array( ), 'aphront-form-view-css' => array( - 'uri' => '/res/1e191b83/rsrc/css/aphront/form-view.css', + 'uri' => '/res/428fbcd8/rsrc/css/aphront/form-view.css', 'type' => 'css', 'requires' => array( @@ -1851,12 +1851,15 @@ celerity_register_resource_map(array( ), 'javelin-behavior-pholio-mock-view' => array( - 'uri' => '/res/10fbdca1/rsrc/js/application/pholio/behavior-pholio-mock-view.js', + 'uri' => '/res/1364872e/rsrc/js/application/pholio/behavior-pholio-mock-view.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', + 2 => 'javelin-dom', + 3 => 'javelin-vector', + 4 => 'javelin-event', ), 'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-view.js', ), @@ -2039,7 +2042,7 @@ celerity_register_resource_map(array( ), 'javelin-event' => array( - 'uri' => '/res/3815b473/rsrc/js/javelin/core/Event.js', + 'uri' => '/res/e6582051/rsrc/js/javelin/core/Event.js', 'type' => 'js', 'requires' => array( @@ -3191,7 +3194,7 @@ celerity_register_resource_map(array( ), 'pholio-css' => array( - 'uri' => '/res/f101ad7c/rsrc/css/application/pholio/pholio.css', + 'uri' => '/res/595f2721/rsrc/css/application/pholio/pholio.css', 'type' => 'css', 'requires' => array( @@ -3381,7 +3384,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - '6ea96b26' => + '7d347135' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -3425,7 +3428,7 @@ celerity_register_resource_map(array( 36 => 'phabricator-object-item-list-view-css', 37 => 'global-drag-and-drop-css', ), - 'uri' => '/res/pkg/6ea96b26/core.pkg.css', + 'uri' => '/res/pkg/7d347135/core.pkg.css', 'type' => 'css', ), '8a3f0fbd' => @@ -3556,7 +3559,7 @@ celerity_register_resource_map(array( 'uri' => '/res/pkg/f96657b8/diffusion.pkg.js', 'type' => 'js', ), - 'fbeded59' => + '88225b70' => array( 'name' => 'javelin.pkg.js', 'symbols' => @@ -3581,7 +3584,7 @@ celerity_register_resource_map(array( 17 => 'javelin-typeahead-ondemand-source', 18 => 'javelin-tokenizer', ), - 'uri' => '/res/pkg/fbeded59/javelin.pkg.js', + 'uri' => '/res/pkg/88225b70/javelin.pkg.js', 'type' => 'js', ), 'e30a3fa8' => @@ -3615,19 +3618,19 @@ celerity_register_resource_map(array( 'reverse' => array( 'aphront-attached-file-view-css' => 'e30a3fa8', - 'aphront-crumbs-view-css' => '6ea96b26', - 'aphront-dialog-view-css' => '6ea96b26', - 'aphront-error-view-css' => '6ea96b26', - 'aphront-form-view-css' => '6ea96b26', + 'aphront-crumbs-view-css' => '7d347135', + 'aphront-dialog-view-css' => '7d347135', + 'aphront-error-view-css' => '7d347135', + 'aphront-form-view-css' => '7d347135', 'aphront-headsup-action-list-view-css' => 'ec01d039', - 'aphront-headsup-view-css' => '6ea96b26', - 'aphront-list-filter-view-css' => '6ea96b26', - 'aphront-pager-view-css' => '6ea96b26', - 'aphront-panel-view-css' => '6ea96b26', - 'aphront-table-view-css' => '6ea96b26', - 'aphront-tokenizer-control-css' => '6ea96b26', - 'aphront-tooltip-css' => '6ea96b26', - 'aphront-typeahead-control-css' => '6ea96b26', + 'aphront-headsup-view-css' => '7d347135', + 'aphront-list-filter-view-css' => '7d347135', + 'aphront-pager-view-css' => '7d347135', + 'aphront-panel-view-css' => '7d347135', + 'aphront-table-view-css' => '7d347135', + 'aphront-tokenizer-control-css' => '7d347135', + 'aphront-tooltip-css' => '7d347135', + 'aphront-typeahead-control-css' => '7d347135', 'differential-changeset-view-css' => 'ec01d039', 'differential-core-view-css' => 'ec01d039', 'differential-inline-comment-editor' => '1b2c991b', @@ -3641,10 +3644,10 @@ celerity_register_resource_map(array( 'differential-table-of-contents-css' => 'ec01d039', 'diffusion-commit-view-css' => 'c8ce2d88', 'diffusion-icons-css' => 'c8ce2d88', - 'global-drag-and-drop-css' => '6ea96b26', + 'global-drag-and-drop-css' => '7d347135', 'inline-comment-summary-css' => 'ec01d039', 'javelin-aphlict' => '8a3f0fbd', - 'javelin-behavior' => 'fbeded59', + 'javelin-behavior' => '88225b70', 'javelin-behavior-aphlict-dropdown' => '8a3f0fbd', 'javelin-behavior-aphlict-listen' => '8a3f0fbd', 'javelin-behavior-aphront-basic-tokenizer' => '8a3f0fbd', @@ -3693,66 +3696,66 @@ celerity_register_resource_map(array( 'javelin-behavior-repository-crossreference' => '1b2c991b', 'javelin-behavior-toggle-class' => '8a3f0fbd', 'javelin-behavior-workflow' => '8a3f0fbd', - 'javelin-dom' => 'fbeded59', - 'javelin-event' => 'fbeded59', - 'javelin-install' => 'fbeded59', - 'javelin-json' => 'fbeded59', - 'javelin-mask' => 'fbeded59', - 'javelin-request' => 'fbeded59', - 'javelin-resource' => 'fbeded59', - 'javelin-stratcom' => 'fbeded59', - 'javelin-tokenizer' => 'fbeded59', - 'javelin-typeahead' => 'fbeded59', - 'javelin-typeahead-normalizer' => 'fbeded59', - 'javelin-typeahead-ondemand-source' => 'fbeded59', - 'javelin-typeahead-preloaded-source' => 'fbeded59', - 'javelin-typeahead-source' => 'fbeded59', - 'javelin-uri' => 'fbeded59', - 'javelin-util' => 'fbeded59', - 'javelin-vector' => 'fbeded59', - 'javelin-workflow' => 'fbeded59', - 'lightbox-attachment-css' => '6ea96b26', + 'javelin-dom' => '88225b70', + 'javelin-event' => '88225b70', + 'javelin-install' => '88225b70', + 'javelin-json' => '88225b70', + 'javelin-mask' => '88225b70', + 'javelin-request' => '88225b70', + 'javelin-resource' => '88225b70', + 'javelin-stratcom' => '88225b70', + 'javelin-tokenizer' => '88225b70', + 'javelin-typeahead' => '88225b70', + 'javelin-typeahead-normalizer' => '88225b70', + 'javelin-typeahead-ondemand-source' => '88225b70', + 'javelin-typeahead-preloaded-source' => '88225b70', + 'javelin-typeahead-source' => '88225b70', + 'javelin-uri' => '88225b70', + 'javelin-util' => '88225b70', + 'javelin-vector' => '88225b70', + 'javelin-workflow' => '88225b70', + 'lightbox-attachment-css' => '7d347135', 'maniphest-task-summary-css' => 'e30a3fa8', 'maniphest-transaction-detail-css' => 'e30a3fa8', 'phabricator-busy' => '8a3f0fbd', 'phabricator-content-source-view-css' => 'ec01d039', - 'phabricator-core-buttons-css' => '6ea96b26', - 'phabricator-core-css' => '6ea96b26', - 'phabricator-crumbs-view-css' => '6ea96b26', - 'phabricator-directory-css' => '6ea96b26', + 'phabricator-core-buttons-css' => '7d347135', + 'phabricator-core-css' => '7d347135', + 'phabricator-crumbs-view-css' => '7d347135', + 'phabricator-directory-css' => '7d347135', 'phabricator-drag-and-drop-file-upload' => '1b2c991b', 'phabricator-dropdown-menu' => '8a3f0fbd', 'phabricator-file-upload' => '8a3f0fbd', - 'phabricator-filetree-view-css' => '6ea96b26', - 'phabricator-flag-css' => '6ea96b26', - 'phabricator-form-view-css' => '6ea96b26', - 'phabricator-header-view-css' => '6ea96b26', - 'phabricator-jump-nav' => '6ea96b26', + 'phabricator-filetree-view-css' => '7d347135', + 'phabricator-flag-css' => '7d347135', + 'phabricator-form-view-css' => '7d347135', + 'phabricator-header-view-css' => '7d347135', + 'phabricator-jump-nav' => '7d347135', 'phabricator-keyboard-shortcut' => '8a3f0fbd', 'phabricator-keyboard-shortcut-manager' => '8a3f0fbd', - 'phabricator-main-menu-view' => '6ea96b26', + 'phabricator-main-menu-view' => '7d347135', 'phabricator-menu-item' => '8a3f0fbd', - 'phabricator-nav-view-css' => '6ea96b26', + 'phabricator-nav-view-css' => '7d347135', 'phabricator-notification' => '8a3f0fbd', - 'phabricator-notification-css' => '6ea96b26', - 'phabricator-notification-menu-css' => '6ea96b26', - 'phabricator-object-item-list-view-css' => '6ea96b26', + 'phabricator-notification-css' => '7d347135', + 'phabricator-notification-menu-css' => '7d347135', + 'phabricator-object-item-list-view-css' => '7d347135', 'phabricator-object-selector-css' => 'ec01d039', 'phabricator-paste-file-upload' => '8a3f0fbd', 'phabricator-prefab' => '8a3f0fbd', 'phabricator-project-tag-css' => 'e30a3fa8', - 'phabricator-remarkup-css' => '6ea96b26', + 'phabricator-remarkup-css' => '7d347135', 'phabricator-shaped-request' => '1b2c991b', - 'phabricator-side-menu-view-css' => '6ea96b26', - 'phabricator-standard-page-view' => '6ea96b26', + 'phabricator-side-menu-view-css' => '7d347135', + 'phabricator-standard-page-view' => '7d347135', 'phabricator-textareautils' => '8a3f0fbd', 'phabricator-tooltip' => '8a3f0fbd', - 'phabricator-transaction-view-css' => '6ea96b26', - 'phabricator-zindex-css' => '6ea96b26', - 'sprite-apps-large-css' => '6ea96b26', - 'sprite-gradient-css' => '6ea96b26', - 'sprite-icon-css' => '6ea96b26', - 'sprite-menu-css' => '6ea96b26', - 'syntax-highlighting-css' => '6ea96b26', + 'phabricator-transaction-view-css' => '7d347135', + 'phabricator-zindex-css' => '7d347135', + 'sprite-apps-large-css' => '7d347135', + 'sprite-gradient-css' => '7d347135', + 'sprite-icon-css' => '7d347135', + 'sprite-menu-css' => '7d347135', + 'syntax-highlighting-css' => '7d347135', ), )); diff --git a/src/view/form/control/AphrontFormImageControl.php b/src/view/form/control/AphrontFormImageControl.php index d0acadb19a..fb5b8bd08c 100644 --- a/src/view/form/control/AphrontFormImageControl.php +++ b/src/view/form/control/AphrontFormImageControl.php @@ -15,7 +15,6 @@ final class AphrontFormImageControl extends AphrontFormControl { array( 'type' => 'file', 'name' => $this->getName(), - 'class' => 'image', )). '
'. phutil_render_tag( diff --git a/webroot/rsrc/css/aphront/form-view.css b/webroot/rsrc/css/aphront/form-view.css index 234e7579a0..52dc73e307 100644 --- a/webroot/rsrc/css/aphront/form-view.css +++ b/webroot/rsrc/css/aphront/form-view.css @@ -187,10 +187,6 @@ table.aphront-form-control-checkbox-layout th { max-width: 400px; } -.aphront-form-control-image .image { - width: 164px; -} - .aphront-form-control-image span { margin: 0px 4px 0px 2px; } From 1322e9eda25ce4ade857a19a54bb25d0ba814902 Mon Sep 17 00:00:00 2001 From: Brennan Taylor Date: Mon, 4 Feb 2013 15:28:09 -0800 Subject: [PATCH 06/13] Implement import profile picture from Gravatar Summary: Add a field where you can put the gravatar email address to pull an image for the profile picture from Test Plan: Tried uploading a file, replacing with default, and various combinations and they all still work. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T2105 Differential Revision: https://secure.phabricator.com/D4809 --- .../files/storage/PhabricatorFile.php | 11 ++- .../storage/PhabricatorFileImageMacro.php | 15 ---- .../panel/PhabricatorSettingsPanelProfile.php | 73 ++++++++++++------- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php index 56fdbbf38b..8a9f486644 100644 --- a/src/applications/files/storage/PhabricatorFile.php +++ b/src/applications/files/storage/PhabricatorFile.php @@ -271,7 +271,7 @@ final class PhabricatorFile extends PhabricatorFileDAO } - public static function newFromFileDownload($uri, $name) { + public static function newFromFileDownload($uri, array $params) { $uri = new PhutilURI($uri); $protocol = $uri->getProtocol(); @@ -286,12 +286,11 @@ final class PhabricatorFile extends PhabricatorFileDAO $timeout = 5; - $file_data = HTTPSFuture::loadContent($uri, $timeout); - if ($file_data === false) { - return null; - } + list($file_data) = id(new HTTPSFuture($uri)) + ->setTimeout($timeout) + ->resolvex(); - return self::newFromFileData($file_data, array('name' => $name)); + return self::newFromFileData($file_data, $params); } public static function normalizeFileName($file_name) { diff --git a/src/applications/macro/storage/PhabricatorFileImageMacro.php b/src/applications/macro/storage/PhabricatorFileImageMacro.php index 2575ffe3e2..9c59f9699f 100644 --- a/src/applications/macro/storage/PhabricatorFileImageMacro.php +++ b/src/applications/macro/storage/PhabricatorFileImageMacro.php @@ -19,21 +19,6 @@ final class PhabricatorFileImageMacro extends PhabricatorFileDAO PhabricatorPHIDConstants::PHID_TYPE_MCRO); } - static public function newFromImageURI($uri, $file_name, $image_macro_name) { - $file = PhabricatorFile::newFromFileDownload($uri, $file_name); - - if (!$file) { - return null; - } - - $image_macro = new PhabricatorFileImageMacro(); - $image_macro->setName($image_macro_name); - $image_macro->setFilePHID($file->getPHID()); - $image_macro->save(); - - return $image_macro; - } - public function isAutomaticallySubscribed($phid) { return false; } diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelProfile.php b/src/applications/settings/panel/PhabricatorSettingsPanelProfile.php index 3eb398aa4b..75cc676da2 100644 --- a/src/applications/settings/panel/PhabricatorSettingsPanelProfile.php +++ b/src/applications/settings/panel/PhabricatorSettingsPanelProfile.php @@ -46,42 +46,57 @@ final class PhabricatorSettingsPanelProfile $user->setTranslation($request->getStr('translation')); $default_image = $request->getExists('default_image'); + $gravatar_email = $request->getStr('gravatar'); if ($default_image) { $profile->setProfileImagePHID(null); $user->setProfileImagePHID(null); - } else if (!empty($_FILES['image'])) { - $err = idx($_FILES['image'], 'error'); - if ($err != UPLOAD_ERR_NO_FILE) { + } else if (!empty($gravatar_email) || $request->getFileExists('image')) { + $file = null; + if (!empty($gravatar_email)) { + // These steps recommended by: + // https://en.gravatar.com/site/implement/hash/ + $trimmed = trim($gravatar_email); + $lower_cased = strtolower($trimmed); + $hash = md5($lower_cased); + $url = 'http://www.gravatar.com/avatar/'.($hash).'?s=200'; + $file = PhabricatorFile::newFromFileDownload( + $url, + array( + 'name' => 'gravatar', + 'authorPHID' => $user->getPHID(), + )); + } else if ($request->getFileExists('image')) { $file = PhabricatorFile::newFromPHPUpload( $_FILES['image'], array( 'authorPHID' => $user->getPHID(), )); - $okay = $file->isTransformableImage(); - if ($okay) { - $xformer = new PhabricatorImageTransformer(); + } - // Generate the large picture for the profile page. - $large_xformed = $xformer->executeProfileTransform( - $file, - $width = 280, - $min_height = 140, - $max_height = 420); - $profile->setProfileImagePHID($large_xformed->getPHID()); + $okay = $file->isTransformableImage(); + if ($okay) { + $xformer = new PhabricatorImageTransformer(); - // Generate the small picture for comments, etc. - $small_xformed = $xformer->executeProfileTransform( - $file, - $width = 50, - $min_height = 50, - $max_height = 50); - $user->setProfileImagePHID($small_xformed->getPHID()); - } else { - $e_image = 'Not Supported'; - $errors[] = - 'This server only supports these image formats: '. - implode(', ', $supported_formats).'.'; - } + // Generate the large picture for the profile page. + $large_xformed = $xformer->executeProfileTransform( + $file, + $width = 280, + $min_height = 140, + $max_height = 420); + $profile->setProfileImagePHID($large_xformed->getPHID()); + + // Generate the small picture for comments, etc. + $small_xformed = $xformer->executeProfileTransform( + $file, + $width = 50, + $min_height = 50, + $max_height = 50); + $user->setProfileImagePHID($small_xformed->getPHID()); + } else { + $e_image = 'Not Supported'; + $errors[] = + 'This server only supports these image formats: '. + implode(', ', $supported_formats).'.'; } } @@ -190,6 +205,12 @@ final class PhabricatorSettingsPanelProfile ->setName('image') ->setError($e_image) ->setCaption('Supported formats: '.implode(', ', $supported_formats))) + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel('Import Gravatar') + ->setName('gravatar') + ->setError($e_image) + ->setCaption('Enter gravatar email address')) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue('Save') From 0bb62d0c3173b7b44d4cb44cb715c91fac02cdc9 Mon Sep 17 00:00:00 2001 From: vrana Date: Mon, 4 Feb 2013 16:13:29 -0800 Subject: [PATCH 07/13] Make collapsed navigation sticky Summary: This is the most requested feature in FB by far. Test Plan: Toggled, verified that data are saved. Reloaded, toggled, toggled, toggled, verified that data are saved. Reloaded. Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D4812 --- .../DifferentialRevisionViewController.php | 5 +++++ ...ferentialChangesetFileTreeSideNavBuilder.php | 7 +++++++ .../storage/PhabricatorUserPreferences.php | 1 + src/view/layout/AphrontSideNavFilterView.php | 17 ++++++++++++++--- .../core/behavior-phabricator-nav.js | 5 ++++- 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php index 2ede65d59b..d55e5d3ce9 100644 --- a/src/applications/differential/controller/DifferentialRevisionViewController.php +++ b/src/applications/differential/controller/DifferentialRevisionViewController.php @@ -408,10 +408,15 @@ final class DifferentialRevisionViewController extends DifferentialController { ->setAnchorName('top') ->setNavigationMarker(true); + $collapsed = $user->loadPreferences()->getPreference( + PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED, + false); + $nav = id(new DifferentialChangesetFileTreeSideNavBuilder()) ->setAnchorName('top') ->setTitle('D'.$revision->getID()) ->setBaseURI(new PhutilURI('/D'.$revision->getID())) + ->setCollapsed((bool)$collapsed) ->build($changesets); $nav->appendChild( array( diff --git a/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php b/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php index e13117d2b5..ecb3e80504 100644 --- a/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php +++ b/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php @@ -5,6 +5,7 @@ final class DifferentialChangesetFileTreeSideNavBuilder { private $title; private $baseURI; private $anchorName; + private $collapsed = false; public function setAnchorName($anchor_name) { $this->anchorName = $anchor_name; @@ -30,12 +31,18 @@ final class DifferentialChangesetFileTreeSideNavBuilder { return $this->title; } + public function setCollapsed($collapsed) { + $this->collapsed = $collapsed; + return $this; + } + public function build(array $changesets) { assert_instances_of($changesets, 'DifferentialChangeset'); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI($this->getBaseURI()); $nav->setFlexible(true); + $nav->setCollapsed($this->collapsed); $anchor = $this->getAnchorName(); diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php index e5910cf833..1b23ee082d 100644 --- a/src/applications/settings/storage/PhabricatorUserPreferences.php +++ b/src/applications/settings/storage/PhabricatorUserPreferences.php @@ -19,6 +19,7 @@ final class PhabricatorUserPreferences extends PhabricatorUserDAO { const PREFERENCE_DIFFUSION_VIEW = 'diffusion-view'; + const PREFERENCE_NAV_COLLAPSED = 'nav-collapsed'; const PREFERENCE_NAV_WIDTH = 'nav-width'; const PREFERENCE_APP_TILES = 'app-tiles'; diff --git a/src/view/layout/AphrontSideNavFilterView.php b/src/view/layout/AphrontSideNavFilterView.php index 1ff467b523..6b17e12024 100644 --- a/src/view/layout/AphrontSideNavFilterView.php +++ b/src/view/layout/AphrontSideNavFilterView.php @@ -21,6 +21,7 @@ final class AphrontSideNavFilterView extends AphrontView { private $baseURI; private $selectedFilter = false; private $flexible; + private $collapsed = false; private $active; private $menu; private $crumbs; @@ -70,6 +71,11 @@ final class AphrontSideNavFilterView extends AphrontView { return $this; } + public function setCollapsed($collapsed) { + $this->collapsed = $collapsed; + return $this; + } + public function getMenuView() { return $this->menu; } @@ -196,7 +202,6 @@ final class AphrontSideNavFilterView extends AphrontView { $main_id = celerity_generate_unique_node_id(); if ($this->flexible) { - $nav_classes[] = 'has-drag-nav'; $drag_id = celerity_generate_unique_node_id(); $flex_bar = phutil_render_tag( 'div', @@ -213,7 +218,10 @@ final class AphrontSideNavFilterView extends AphrontView { if ($this->menu->getItems()) { $local_id = celerity_generate_unique_node_id(); $background_id = celerity_generate_unique_node_id(); - $nav_classes[] = 'has-local-nav'; + + if (!$this->collapsed) { + $nav_classes[] = 'has-local-nav'; + } $menu_background = phutil_render_tag( 'div', @@ -240,7 +248,9 @@ final class AphrontSideNavFilterView extends AphrontView { } if ($this->flexible) { - $nav_classes[] = 'has-drag-nav'; + if (!$this->collapsed) { + $nav_classes[] = 'has-drag-nav'; + } Javelin::initBehavior( 'phabricator-nav', @@ -250,6 +260,7 @@ final class AphrontSideNavFilterView extends AphrontView { 'dragID' => $drag_id, 'contentID' => $content_id, 'backgroundID' => $background_id, + 'collapsed' => $this->collapsed, )); if ($this->active) { diff --git a/webroot/rsrc/js/application/core/behavior-phabricator-nav.js b/webroot/rsrc/js/application/core/behavior-phabricator-nav.js index eae6708061..0df0967279 100644 --- a/webroot/rsrc/js/application/core/behavior-phabricator-nav.js +++ b/webroot/rsrc/js/application/core/behavior-phabricator-nav.js @@ -109,12 +109,15 @@ JX.behavior('phabricator-nav', function(config) { content.style.marginLeft = ''; } - var collapsed = false; + var collapsed = config.collapsed; JX.Stratcom.listen('differential-filetree-toggle', null, function(e) { collapsed = !collapsed; JX.DOM.alterClass(main, 'has-local-nav', !collapsed); JX.DOM.alterClass(main, 'has-drag-nav', !collapsed); resetdrag(); + new JX.Request('/settings/adjust/', JX.Bag) + .setData({ key : 'nav-collapsed', value : (collapsed ? 1 : 0) }) + .send(); }); From af1f57b37ac3e96eaa157ab11e3564a6fb19e16b Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 4 Feb 2013 17:00:27 -0800 Subject: [PATCH 08/13] Add a preference to completely disable the file tree Summary: See D4812. - This preference disables the file tree completely. - It defaults off, so users who want it will have to go turn it on. - Maybe slightly cleaner would be doing this if the tree was hidden and then ajaxing it in if you press "F", but that's complicated and I don't want to bother. - Generally, I think this element is useful to something like 5% of users and not useful to 95%. Test Plan: Enabled and disabled file tree. Looked at commits and revisions; verified they reflected the setting correctly. Reviewers: vrana Reviewed By: vrana CC: aran Differential Revision: https://secure.phabricator.com/D4813 --- src/__celerity_resource_map__.php | 128 ++++++++++-------- src/__phutil_library_map__.php | 2 + .../DifferentialRevisionViewController.php | 48 ++++--- ...rentialChangesetFileTreeSideNavBuilder.php | 2 + .../controller/DiffusionCommitController.php | 9 +- ...habricatorSettingsPanelDiffPreferences.php | 72 ++++++++++ .../storage/PhabricatorUserPreferences.php | 2 + .../js/application/core/behavior-file-tree.js | 16 +++ .../differential/behavior-keyboard-nav.js | 6 - 9 files changed, 200 insertions(+), 85 deletions(-) create mode 100644 src/applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php create mode 100644 webroot/rsrc/js/application/core/behavior-file-tree.js diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 3df75ec35a..7693a108a5 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -1292,7 +1292,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-differential-keyboard-navigation' => array( - 'uri' => '/res/a7798465/rsrc/js/application/differential/behavior-keyboard-nav.js', + 'uri' => '/res/89e93cc9/rsrc/js/application/differential/behavior-keyboard-nav.js', 'type' => 'js', 'requires' => array( @@ -1664,6 +1664,18 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/application/core/behavior-autofocus.js', ), + 'javelin-behavior-phabricator-file-tree' => + array( + 'uri' => '/res/e9c96597/rsrc/js/application/core/behavior-file-tree.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-behavior', + 1 => 'phabricator-keyboard-shortcut', + 2 => 'javelin-stratcom', + ), + 'disk' => '/rsrc/js/application/core/behavior-file-tree.js', + ), 'javelin-behavior-phabricator-home-reveal-tiles' => array( 'uri' => '/res/7230ca0c/rsrc/js/application/core/behavior-home-reveal-tiles.js', @@ -1704,7 +1716,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-phabricator-nav' => array( - 'uri' => '/res/cec31f3f/rsrc/js/application/core/behavior-phabricator-nav.js', + 'uri' => '/res/222b9329/rsrc/js/application/core/behavior-phabricator-nav.js', 'type' => 'js', 'requires' => array( @@ -3431,7 +3443,7 @@ celerity_register_resource_map(array( 'uri' => '/res/pkg/7d347135/core.pkg.css', 'type' => 'css', ), - '8a3f0fbd' => + '22373a47' => array( 'name' => 'core.pkg.js', 'symbols' => @@ -3470,7 +3482,7 @@ celerity_register_resource_map(array( 31 => 'javelin-behavior-global-drag-and-drop', 32 => 'javelin-behavior-phabricator-home-reveal-tiles', ), - 'uri' => '/res/pkg/8a3f0fbd/core.pkg.js', + 'uri' => '/res/pkg/22373a47/core.pkg.js', 'type' => 'js', ), '8edbada5' => @@ -3508,7 +3520,7 @@ celerity_register_resource_map(array( 'uri' => '/res/pkg/ec01d039/differential.pkg.css', 'type' => 'css', ), - '1b2c991b' => + '95d0d865' => array( 'name' => 'differential.pkg.js', 'symbols' => @@ -3533,7 +3545,7 @@ celerity_register_resource_map(array( 17 => 'javelin-behavior-differential-toggle-files', 18 => 'javelin-behavior-differential-user-select', ), - 'uri' => '/res/pkg/1b2c991b/differential.pkg.js', + 'uri' => '/res/pkg/95d0d865/differential.pkg.js', 'type' => 'js', ), 'c8ce2d88' => @@ -3633,7 +3645,7 @@ celerity_register_resource_map(array( 'aphront-typeahead-control-css' => '7d347135', 'differential-changeset-view-css' => 'ec01d039', 'differential-core-view-css' => 'ec01d039', - 'differential-inline-comment-editor' => '1b2c991b', + 'differential-inline-comment-editor' => '95d0d865', 'differential-local-commits-view-css' => 'ec01d039', 'differential-results-table-css' => 'ec01d039', 'differential-revision-add-comment-css' => 'ec01d039', @@ -3646,56 +3658,56 @@ celerity_register_resource_map(array( 'diffusion-icons-css' => 'c8ce2d88', 'global-drag-and-drop-css' => '7d347135', 'inline-comment-summary-css' => 'ec01d039', - 'javelin-aphlict' => '8a3f0fbd', + 'javelin-aphlict' => '22373a47', 'javelin-behavior' => '88225b70', - 'javelin-behavior-aphlict-dropdown' => '8a3f0fbd', - 'javelin-behavior-aphlict-listen' => '8a3f0fbd', - 'javelin-behavior-aphront-basic-tokenizer' => '8a3f0fbd', - 'javelin-behavior-aphront-drag-and-drop' => '1b2c991b', - 'javelin-behavior-aphront-drag-and-drop-textarea' => '1b2c991b', - 'javelin-behavior-aphront-form-disable-on-submit' => '8a3f0fbd', + 'javelin-behavior-aphlict-dropdown' => '22373a47', + 'javelin-behavior-aphlict-listen' => '22373a47', + 'javelin-behavior-aphront-basic-tokenizer' => '22373a47', + 'javelin-behavior-aphront-drag-and-drop' => '95d0d865', + 'javelin-behavior-aphront-drag-and-drop-textarea' => '95d0d865', + 'javelin-behavior-aphront-form-disable-on-submit' => '22373a47', 'javelin-behavior-audit-preview' => 'f96657b8', 'javelin-behavior-dark-console' => '8edbada5', 'javelin-behavior-dark-console-ajax' => '8edbada5', - 'javelin-behavior-device' => '8a3f0fbd', - 'javelin-behavior-differential-accept-with-errors' => '1b2c991b', - 'javelin-behavior-differential-add-reviewers-and-ccs' => '1b2c991b', - 'javelin-behavior-differential-comment-jump' => '1b2c991b', - 'javelin-behavior-differential-diff-radios' => '1b2c991b', - 'javelin-behavior-differential-dropdown-menus' => '1b2c991b', - 'javelin-behavior-differential-edit-inline-comments' => '1b2c991b', - 'javelin-behavior-differential-feedback-preview' => '1b2c991b', - 'javelin-behavior-differential-keyboard-navigation' => '1b2c991b', - 'javelin-behavior-differential-populate' => '1b2c991b', - 'javelin-behavior-differential-show-more' => '1b2c991b', - 'javelin-behavior-differential-toggle-files' => '1b2c991b', - 'javelin-behavior-differential-user-select' => '1b2c991b', + 'javelin-behavior-device' => '22373a47', + 'javelin-behavior-differential-accept-with-errors' => '95d0d865', + 'javelin-behavior-differential-add-reviewers-and-ccs' => '95d0d865', + 'javelin-behavior-differential-comment-jump' => '95d0d865', + 'javelin-behavior-differential-diff-radios' => '95d0d865', + 'javelin-behavior-differential-dropdown-menus' => '95d0d865', + 'javelin-behavior-differential-edit-inline-comments' => '95d0d865', + 'javelin-behavior-differential-feedback-preview' => '95d0d865', + 'javelin-behavior-differential-keyboard-navigation' => '95d0d865', + 'javelin-behavior-differential-populate' => '95d0d865', + 'javelin-behavior-differential-show-more' => '95d0d865', + 'javelin-behavior-differential-toggle-files' => '95d0d865', + 'javelin-behavior-differential-user-select' => '95d0d865', 'javelin-behavior-diffusion-commit-graph' => 'f96657b8', 'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8', 'javelin-behavior-error-log' => '8edbada5', - 'javelin-behavior-global-drag-and-drop' => '8a3f0fbd', - 'javelin-behavior-konami' => '8a3f0fbd', - 'javelin-behavior-lightbox-attachments' => '8a3f0fbd', + 'javelin-behavior-global-drag-and-drop' => '22373a47', + 'javelin-behavior-konami' => '22373a47', + 'javelin-behavior-lightbox-attachments' => '22373a47', 'javelin-behavior-maniphest-batch-selector' => '7707de41', 'javelin-behavior-maniphest-subpriority-editor' => '7707de41', 'javelin-behavior-maniphest-transaction-controls' => '7707de41', 'javelin-behavior-maniphest-transaction-expand' => '7707de41', 'javelin-behavior-maniphest-transaction-preview' => '7707de41', - 'javelin-behavior-phabricator-active-nav' => '8a3f0fbd', - 'javelin-behavior-phabricator-autofocus' => '8a3f0fbd', - 'javelin-behavior-phabricator-home-reveal-tiles' => '8a3f0fbd', - 'javelin-behavior-phabricator-keyboard-shortcuts' => '8a3f0fbd', - 'javelin-behavior-phabricator-nav' => '8a3f0fbd', - 'javelin-behavior-phabricator-object-selector' => '1b2c991b', - 'javelin-behavior-phabricator-oncopy' => '8a3f0fbd', - 'javelin-behavior-phabricator-remarkup-assist' => '8a3f0fbd', - 'javelin-behavior-phabricator-search-typeahead' => '8a3f0fbd', - 'javelin-behavior-phabricator-tooltips' => '8a3f0fbd', - 'javelin-behavior-phabricator-watch-anchor' => '8a3f0fbd', - 'javelin-behavior-refresh-csrf' => '8a3f0fbd', - 'javelin-behavior-repository-crossreference' => '1b2c991b', - 'javelin-behavior-toggle-class' => '8a3f0fbd', - 'javelin-behavior-workflow' => '8a3f0fbd', + 'javelin-behavior-phabricator-active-nav' => '22373a47', + 'javelin-behavior-phabricator-autofocus' => '22373a47', + 'javelin-behavior-phabricator-home-reveal-tiles' => '22373a47', + 'javelin-behavior-phabricator-keyboard-shortcuts' => '22373a47', + 'javelin-behavior-phabricator-nav' => '22373a47', + 'javelin-behavior-phabricator-object-selector' => '95d0d865', + 'javelin-behavior-phabricator-oncopy' => '22373a47', + 'javelin-behavior-phabricator-remarkup-assist' => '22373a47', + 'javelin-behavior-phabricator-search-typeahead' => '22373a47', + 'javelin-behavior-phabricator-tooltips' => '22373a47', + 'javelin-behavior-phabricator-watch-anchor' => '22373a47', + 'javelin-behavior-refresh-csrf' => '22373a47', + 'javelin-behavior-repository-crossreference' => '95d0d865', + 'javelin-behavior-toggle-class' => '22373a47', + 'javelin-behavior-workflow' => '22373a47', 'javelin-dom' => '88225b70', 'javelin-event' => '88225b70', 'javelin-install' => '88225b70', @@ -3717,39 +3729,39 @@ celerity_register_resource_map(array( 'lightbox-attachment-css' => '7d347135', 'maniphest-task-summary-css' => 'e30a3fa8', 'maniphest-transaction-detail-css' => 'e30a3fa8', - 'phabricator-busy' => '8a3f0fbd', + 'phabricator-busy' => '22373a47', 'phabricator-content-source-view-css' => 'ec01d039', 'phabricator-core-buttons-css' => '7d347135', 'phabricator-core-css' => '7d347135', 'phabricator-crumbs-view-css' => '7d347135', 'phabricator-directory-css' => '7d347135', - 'phabricator-drag-and-drop-file-upload' => '1b2c991b', - 'phabricator-dropdown-menu' => '8a3f0fbd', - 'phabricator-file-upload' => '8a3f0fbd', + 'phabricator-drag-and-drop-file-upload' => '95d0d865', + 'phabricator-dropdown-menu' => '22373a47', + 'phabricator-file-upload' => '22373a47', 'phabricator-filetree-view-css' => '7d347135', 'phabricator-flag-css' => '7d347135', 'phabricator-form-view-css' => '7d347135', 'phabricator-header-view-css' => '7d347135', 'phabricator-jump-nav' => '7d347135', - 'phabricator-keyboard-shortcut' => '8a3f0fbd', - 'phabricator-keyboard-shortcut-manager' => '8a3f0fbd', + 'phabricator-keyboard-shortcut' => '22373a47', + 'phabricator-keyboard-shortcut-manager' => '22373a47', 'phabricator-main-menu-view' => '7d347135', - 'phabricator-menu-item' => '8a3f0fbd', + 'phabricator-menu-item' => '22373a47', 'phabricator-nav-view-css' => '7d347135', - 'phabricator-notification' => '8a3f0fbd', + 'phabricator-notification' => '22373a47', 'phabricator-notification-css' => '7d347135', 'phabricator-notification-menu-css' => '7d347135', 'phabricator-object-item-list-view-css' => '7d347135', 'phabricator-object-selector-css' => 'ec01d039', - 'phabricator-paste-file-upload' => '8a3f0fbd', - 'phabricator-prefab' => '8a3f0fbd', + 'phabricator-paste-file-upload' => '22373a47', + 'phabricator-prefab' => '22373a47', 'phabricator-project-tag-css' => 'e30a3fa8', 'phabricator-remarkup-css' => '7d347135', - 'phabricator-shaped-request' => '1b2c991b', + 'phabricator-shaped-request' => '95d0d865', 'phabricator-side-menu-view-css' => '7d347135', 'phabricator-standard-page-view' => '7d347135', - 'phabricator-textareautils' => '8a3f0fbd', - 'phabricator-tooltip' => '8a3f0fbd', + 'phabricator-textareautils' => '22373a47', + 'phabricator-tooltip' => '22373a47', 'phabricator-transaction-view-css' => '7d347135', 'phabricator-zindex-css' => '7d347135', 'sprite-apps-large-css' => '7d347135', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 83d988c22d..b40b32e2a1 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1228,6 +1228,7 @@ phutil_register_library_map(array( 'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php', 'PhabricatorSettingsPanelAccount' => 'applications/settings/panel/PhabricatorSettingsPanelAccount.php', 'PhabricatorSettingsPanelConduit' => 'applications/settings/panel/PhabricatorSettingsPanelConduit.php', + 'PhabricatorSettingsPanelDiffPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php', 'PhabricatorSettingsPanelDisplayPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php', 'PhabricatorSettingsPanelEmailAddresses' => 'applications/settings/panel/PhabricatorSettingsPanelEmailAddresses.php', 'PhabricatorSettingsPanelEmailPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelEmailPreferences.php', @@ -2628,6 +2629,7 @@ phutil_register_library_map(array( 'PhabricatorSettingsMainController' => 'PhabricatorController', 'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel', 'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel', + 'PhabricatorSettingsPanelDiffPreferences' => 'PhabricatorSettingsPanel', 'PhabricatorSettingsPanelDisplayPreferences' => 'PhabricatorSettingsPanel', 'PhabricatorSettingsPanelEmailAddresses' => 'PhabricatorSettingsPanel', 'PhabricatorSettingsPanelEmailPreferences' => 'PhabricatorSettingsPanel', diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php index d55e5d3ce9..a5f8c41095 100644 --- a/src/applications/differential/controller/DifferentialRevisionViewController.php +++ b/src/applications/differential/controller/DifferentialRevisionViewController.php @@ -408,34 +408,42 @@ final class DifferentialRevisionViewController extends DifferentialController { ->setAnchorName('top') ->setNavigationMarker(true); - $collapsed = $user->loadPreferences()->getPreference( - PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED, - false); - - $nav = id(new DifferentialChangesetFileTreeSideNavBuilder()) - ->setAnchorName('top') - ->setTitle('D'.$revision->getID()) - ->setBaseURI(new PhutilURI('/D'.$revision->getID())) - ->setCollapsed((bool)$collapsed) - ->build($changesets); - $nav->appendChild( - array( - $reviewer_warning, - $top_anchor, - $revision_detail, - $page_pane, - )); - + $content = array( + $reviewer_warning, + $top_anchor, + $revision_detail, + $page_pane, + ); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addCrumb( id(new PhabricatorCrumbView()) ->setName($object_id) ->setHref('/'.$object_id)); - $nav->setCrumbs($crumbs); + + $prefs = $user->loadPreferences(); + + $pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE; + if ($prefs->getPreference($pref_filetree)) { + $collapsed = $prefs->getPreference( + PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED, + false); + + $nav = id(new DifferentialChangesetFileTreeSideNavBuilder()) + ->setAnchorName('top') + ->setTitle('D'.$revision->getID()) + ->setBaseURI(new PhutilURI('/D'.$revision->getID())) + ->setCollapsed((bool)$collapsed) + ->build($changesets); + $nav->appendChild($content); + $nav->setCrumbs($crumbs); + $content = $nav; + } else { + array_unshift($content, $crumbs); + } return $this->buildApplicationPage( - $nav, + $content, array( 'title' => $object_id.' '.$revision->getTitle(), )); diff --git a/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php b/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php index ecb3e80504..d3ae1ad744 100644 --- a/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php +++ b/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php @@ -123,6 +123,8 @@ final class DifferentialChangesetFileTreeSideNavBuilder { } $tree->destroy(); + Javelin::initBehavior('phabricator-file-tree', array()); + $filetree = '
'. implode("\n", $filetree). diff --git a/src/applications/diffusion/controller/DiffusionCommitController.php b/src/applications/diffusion/controller/DiffusionCommitController.php index 69f96d2537..d9f2bee1ea 100644 --- a/src/applications/diffusion/controller/DiffusionCommitController.php +++ b/src/applications/diffusion/controller/DiffusionCommitController.php @@ -324,13 +324,20 @@ final class DiffusionCommitController extends DiffusionController { 'commit' => true, )); - if ($changesets) { + $prefs = $user->loadPreferences(); + $pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE; + $pref_collapse = PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED; + $show_filetree = $prefs->getPreference($pref_filetree); + $collapsed = $prefs->getPreference($pref_collapse); + + if ($changesets && $show_filetree) { $nav = id(new DifferentialChangesetFileTreeSideNavBuilder()) ->setAnchorName('top') ->setTitle($short_name) ->setBaseURI(new PhutilURI('/'.$commit_id)) ->build($changesets) ->setCrumbs($crumbs) + ->setCollapsed((bool)$collapsed) ->appendChild($content); $content = $nav; } else { diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php b/src/applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php new file mode 100644 index 0000000000..b6dc0afc3c --- /dev/null +++ b/src/applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php @@ -0,0 +1,72 @@ +getUser(); + $preferences = $user->loadPreferences(); + + $pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE; + + if ($request->isFormPost()) { + $preferences->setPreference( + $pref_filetree, + $request->getInt($pref_filetree)); + + $preferences->save(); + return id(new AphrontRedirectResponse()) + ->setURI($this->getPanelURI('?saved=true')); + } + + $form = id(new AphrontFormView()) + ->setUser($user) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel(pht('Show Filetree')) + ->setName($pref_filetree) + ->setValue($preferences->getPreference($pref_filetree)) + ->setOptions( + array( + 0 => pht('Disable Filetree'), + 1 => pht('Enable Filetree'), + )) + ->setCaption( + pht("When looking at a revision or commit, show affected files ". + "in a sidebar."))) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue(pht('Save Preferences'))); + + $panel = new AphrontPanelView(); + $panel->setHeader(pht('Diff Preferences')); + $panel->appendChild($form); + $panel->setNoBackground(); + + $error_view = null; + if ($request->getBool('saved')) { + $error_view = id(new AphrontErrorView()) + ->setTitle(pht('Preferences Saved')) + ->setSeverity(AphrontErrorView::SEVERITY_NOTICE) + ->setErrors(array(pht('Your preferences have been saved.'))); + } + + return array( + $error_view, + $panel, + ); + } +} + diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php index 1b23ee082d..9f5196a215 100644 --- a/src/applications/settings/storage/PhabricatorUserPreferences.php +++ b/src/applications/settings/storage/PhabricatorUserPreferences.php @@ -23,6 +23,8 @@ final class PhabricatorUserPreferences extends PhabricatorUserDAO { const PREFERENCE_NAV_WIDTH = 'nav-width'; const PREFERENCE_APP_TILES = 'app-tiles'; + const PREFERENCE_DIFF_FILETREE = 'diff-filetree'; + protected $userPHID; protected $preferences = array(); diff --git a/webroot/rsrc/js/application/core/behavior-file-tree.js b/webroot/rsrc/js/application/core/behavior-file-tree.js new file mode 100644 index 0000000000..d5b908eb75 --- /dev/null +++ b/webroot/rsrc/js/application/core/behavior-file-tree.js @@ -0,0 +1,16 @@ +/** + * @provides javelin-behavior-phabricator-file-tree + * @requires javelin-behavior + * phabricator-keyboard-shortcut + * javelin-stratcom + */ + +JX.behavior('phabricator-file-tree', function(config) { + + new JX.KeyboardShortcut('f', 'Toggle file tree.') + .setHandler(function(manager) { + JX.Stratcom.invoke('differential-filetree-toggle'); + }) + .register(); + +}); diff --git a/webroot/rsrc/js/application/differential/behavior-keyboard-nav.js b/webroot/rsrc/js/application/differential/behavior-keyboard-nav.js index 46695a43a8..ef9baae675 100644 --- a/webroot/rsrc/js/application/differential/behavior-keyboard-nav.js +++ b/webroot/rsrc/js/application/differential/behavior-keyboard-nav.js @@ -264,12 +264,6 @@ JX.behavior('differential-keyboard-navigation', function(config) { }) .register(); - new JX.KeyboardShortcut('f', 'Toggle file tree.') - .setHandler(function(manager) { - JX.Stratcom.invoke('differential-filetree-toggle'); - }) - .register(); - if (config.haunt) { new JX.KeyboardShortcut('z', 'Cycle comment panel haunting modes.') .setHandler(haunt) From c7635d8bc681284bfc1b57cd02b386cfe2855a01 Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Mon, 4 Feb 2013 18:32:03 -0800 Subject: [PATCH 09/13] fix space derp from cowboy commit rPc046aa64c16c7c2f956addba06dc7127a9f917be Summary: yeehaw Test Plan: also, yeehaw Reviewers: vrana, epriestley Reviewed By: epriestley CC: aran, epriestley Differential Revision: https://secure.phabricator.com/D4815 --- .../markup/rule/PhabricatorRemarkupRuleImageMacro.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php index 796b408828..4fb3bfb5fc 100644 --- a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php +++ b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php @@ -34,7 +34,7 @@ final class PhabricatorRemarkupRuleImageMacro if ($file) { $src_uri = $file->getBestURI(); $file_data = $file->getMetadata(); - $height = idx($file_data,PhabricatorFile::METADATA_IMAGE_HEIGHT); + $height = idx($file_data, PhabricatorFile::METADATA_IMAGE_HEIGHT); $width = idx($file_data, PhabricatorFile::METADATA_IMAGE_WIDTH); if ($height && $width) { $style = sprintf( From 112c2ebfbe5f596b7a9b8893214a4d1d4b61ae1d Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Mon, 4 Feb 2013 18:59:46 -0800 Subject: [PATCH 10/13] make sort controls only show up if sorting will work Summary: T2326 tells the tale. this is the fix. Test Plan: verified that queries that shouldn't be sortable weren't. also had a phlog in there a bit to sanity check things faster Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T2326 Differential Revision: https://secure.phabricator.com/D4816 --- .../maniphest/controller/ManiphestTaskListController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/applications/maniphest/controller/ManiphestTaskListController.php b/src/applications/maniphest/controller/ManiphestTaskListController.php index 3b8db2ed52..971d9ea70e 100644 --- a/src/applications/maniphest/controller/ManiphestTaskListController.php +++ b/src/applications/maniphest/controller/ManiphestTaskListController.php @@ -330,8 +330,8 @@ final class ManiphestTaskListController extends ManiphestController { $group = $query->getParameter('group'); $order = $query->getParameter('order'); $is_draggable = - ($group == 'priority') || - ($group == 'none' && $order == 'priority'); + ($order == 'priority') && + ($group == 'none' || $group == 'priority'); $lists = new AphrontNullView(); $lists->appendChild('
'); From a211f977375d917b2f7a313225c22d0f3a2968ee Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Mon, 4 Feb 2013 19:01:46 -0800 Subject: [PATCH 11/13] Conpherence - some widget and display stuff Summary: this was originally "just" adding the icons like I had bundled into D4790. It morphed a bit though and does a few things - adds the icons - cleans up widget CSS generally a bit so scrolling always works - phutil_tag -- probably was a bad idea but I wanted to play with it. I think its harder to not break conpherence when you land the branch now maybs. Still up for fixing it immediately post land though. Test Plan: played with conphernece a bit. Used FF and Chrome to verify CSS was looking okay-ish. Reviewers: epriestley, chad Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T2399 Differential Revision: https://secure.phabricator.com/D4814 --- .../controller/ConpherenceController.php | 2 +- .../controller/ConpherenceListController.php | 64 +++--- .../controller/ConpherenceNewController.php | 2 +- .../ConpherenceUpdateController.php | 2 +- .../controller/ConpherenceViewController.php | 193 ++++++++++++++---- .../query/ConpherenceThreadQuery.php | 18 +- .../view/ConpherenceMenuItemView.php | 18 +- .../view/ConpherenceTransactionView.php | 6 +- .../application/conpherence/widget-pane.css | 79 +++++++ webroot/rsrc/css/sprite-conph.css | 4 +- .../conpherence/behavior-widget-pane.js | 7 + 11 files changed, 304 insertions(+), 91 deletions(-) diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php index 7151c0fcc4..033e47f690 100644 --- a/src/applications/conpherence/controller/ConpherenceController.php +++ b/src/applications/conpherence/controller/ConpherenceController.php @@ -166,7 +166,7 @@ abstract class ConpherenceController extends PhabricatorController { private function getNoConpherencesBlock() { - return phutil_render_tag( + return phutil_tag( 'div', array( 'class' => 'no-conpherences-menu-item' diff --git a/src/applications/conpherence/controller/ConpherenceListController.php b/src/applications/conpherence/controller/ConpherenceListController.php index 916d044e86..58aabb58fb 100644 --- a/src/applications/conpherence/controller/ConpherenceListController.php +++ b/src/applications/conpherence/controller/ConpherenceListController.php @@ -65,51 +65,55 @@ final class ConpherenceListController extends private function renderEmptyMainPane() { $this->initJavelinBehaviors(); - return phutil_render_tag( + return phutil_tag( 'div', array( 'id' => 'conpherence-main-pane' ), - phutil_render_tag( - 'div', - array( - 'class' => 'conpherence-header-pane', - 'id' => 'conpherence-header-pane', - ), - '' - ). - phutil_render_tag( - 'div', - array( - 'class' => 'conpherence-widget-pane', - 'id' => 'conpherence-widget-pane' - ), - '' - ). - javelin_render_tag( - 'div', - array( - 'class' => 'conpherence-message-pane', - 'id' => 'conpherence-message-pane' - ), - phutil_render_tag( + array( + phutil_tag( 'div', array( - 'class' => 'conpherence-messages', - 'id' => 'conpherence-messages' + 'class' => 'conpherence-header-pane', + 'id' => 'conpherence-header-pane', ), '' - ). - phutil_render_tag( + ), + phutil_tag( 'div', array( - 'id' => 'conpherence-form' + 'class' => 'conpherence-widget-pane', + 'id' => 'conpherence-widget-pane' ), '' + ), + javelin_tag( + 'div', + array( + 'class' => 'conpherence-message-pane', + 'id' => 'conpherence-message-pane' + ), + array( + phutil_tag( + 'div', + array( + 'class' => 'conpherence-messages', + 'id' => 'conpherence-messages' + ), + '' + ), + phutil_tag( + 'div', + array( + 'id' => 'conpherence-form' + ), + '' + ) + ) ) ) ); } -} + } diff --git a/src/applications/conpherence/controller/ConpherenceNewController.php b/src/applications/conpherence/controller/ConpherenceNewController.php index 43f1ae87f9..623d681535 100644 --- a/src/applications/conpherence/controller/ConpherenceNewController.php +++ b/src/applications/conpherence/controller/ConpherenceNewController.php @@ -92,7 +92,7 @@ final class ConpherenceNewController extends ConpherenceController { ->setTitle('Success') ->addCancelButton('#', 'Okay') ->appendChild( - phutil_render_tag('p', + phutil_tag('p', array(), pht('Message sent successfully.') ) diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index 1f984529c2..2d8deee715 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -135,7 +135,7 @@ final class ConpherenceUpdateController extends ->appendChild( id(new AphrontFormMarkupControl()) ->setLabel(pht('Image')) - ->setValue(phutil_render_tag( + ->setValue(phutil_tag( 'img', array( 'src' => $conpherence->loadImageURI(), diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php index 11cdc8d586..f082ccf78c 100644 --- a/src/applications/conpherence/controller/ConpherenceViewController.php +++ b/src/applications/conpherence/controller/ConpherenceViewController.php @@ -71,7 +71,7 @@ final class ConpherenceViewController extends $edit_href = $this->getApplicationURI('update/'.$conpherence->getID().'/'); $header = - javelin_render_tag( + javelin_tag( 'a', array( 'class' => 'edit', @@ -80,7 +80,7 @@ final class ConpherenceViewController extends ), '' ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'header-image', @@ -88,19 +88,19 @@ final class ConpherenceViewController extends ), '' ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'title', ), - phutil_escape_html($display_data['title']) + $display_data['title'] ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'subtitle', ), - phutil_escape_html($display_data['subtitle']) + $display_data['subtitle'] ); return array('header' => $header); @@ -152,6 +152,7 @@ final class ConpherenceViewController extends private function renderWidgetPaneContent() { require_celerity_resource('conpherence-widget-pane-css'); + require_celerity_resource('sprite-conpher-css'); Javelin::initBehavior( 'conpherence-widget-pane', array( @@ -165,37 +166,54 @@ final class ConpherenceViewController extends $conpherence = $this->getConpherence(); - $widgets = phutil_render_tag( + $widgets = phutil_tag( 'div', array( 'class' => 'widgets-header' ), - javelin_render_tag( - 'a', - array( - 'sigil' => 'conpherence-change-widget', - 'meta' => array('widget' => 'widgets-files') + array( + javelin_tag( + 'a', + array( + 'sigil' => 'conpherence-change-widget', + 'meta' => array( + 'widget' => 'widgets-files', + 'toggleClass' => 'conpher_files_on' + ), + 'id' => 'widgets-files-toggle', + 'class' => 'sprite-conpher conpher_files_off first-icon' + ), + '' ), - pht('Files') - ).' | '. - javelin_render_tag( - 'a', - array( - 'sigil' => 'conpherence-change-widget', - 'meta' => array('widget' => 'widgets-tasks') + javelin_tag( + 'a', + array( + 'sigil' => 'conpherence-change-widget', + 'meta' => array( + 'widget' => 'widgets-tasks', + 'toggleClass' => 'conpher_list_on' + ), + 'id' => 'widgets-tasks-toggle', + 'class' => 'sprite-conpher conpher_list_off conpher_list_on', + ), + '' ), - pht('Tasks') - ).' | '. - javelin_render_tag( - 'a', - array( - 'sigil' => 'conpherence-change-widget', - 'meta' => array('widget' => 'widgets-calendar') - ), - pht('Calendar') + javelin_tag( + 'a', + array( + 'sigil' => 'conpherence-change-widget', + 'meta' => array( + 'widget' => 'widgets-calendar', + 'toggleClass' => 'conpher_calendar_on' + ), + 'id' => 'widgets-calendar-toggle', + 'class' => 'sprite-conpher conpher_calendar_off', + ), + '' + ) ) ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'widgets-body', @@ -204,7 +222,7 @@ final class ConpherenceViewController extends ), $this->renderFilesWidgetPaneContent() ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'widgets-body', @@ -212,7 +230,7 @@ final class ConpherenceViewController extends ), $this->renderTaskWidgetPaneContent() ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'widgets-body', @@ -234,7 +252,7 @@ final class ConpherenceViewController extends foreach ($files as $file) { $thumb = $file->getThumb60x45URI(); $table_data[] = array( - phutil_render_tag( + phutil_tag( 'img', array( 'src' => $thumb @@ -250,7 +268,7 @@ final class ConpherenceViewController extends ->setNoDataString(pht('No files attached to conpherence.')) ->setHeaders(array('', pht('Name'))) ->setColumnClasses(array('', 'wide')); - return $header->render() . $table->render(); + return new PhutilSafeHTML($header->render() . $table->render()); } private function renderTaskWidgetPaneContent() { @@ -271,12 +289,12 @@ final class ConpherenceViewController extends foreach ($actual_tasks as $task) { $data[] = array( idx($priority_map, $task->getPriority(), pht('???')), - phutil_render_tag( + phutil_tag( 'a', array( 'href' => '/T'.$task->getID() ), - phutil_escape_html($task->getTitle()) + $task->getTitle() ) ); } @@ -286,13 +304,110 @@ final class ConpherenceViewController extends ->setColumnClasses(array('', 'wide')); $content[] = $table->render(); } - return implode('', $content); + return new PhutilSafeHTML(implode('', $content)); } private function renderCalendarWidgetPaneContent() { - $header = id(new PhabricatorHeaderView()) - ->setHeader(pht('Calendar')); - return $header->render() . 'TODO'; + $user = $this->getRequest()->getUser(); + + $conpherence = $this->getConpherence(); + $widget_data = $conpherence->getWidgetData(); + $statuses = $widget_data['statuses']; + $handles = $conpherence->getHandles(); + $content = array(); + $timestamps = $this->getCalendarWidgetWeekTimestamps(); + $one_day = 24 * 60 * 60; + foreach ($timestamps as $time => $day) { + // build a header for the new day + $content[] = id(new PhabricatorHeaderView()) + ->setHeader($day->format('l')) + ->render(); + + $day->setTime(0, 0, 0); + $epoch_start = $day->format('U'); + $day->modify('+1 day'); + $epoch_end = $day->format('U'); + + // keep looking through statuses where we last left off + foreach ($statuses as $status) { + if ($status->getDateFrom() >= $epoch_end) { + // This list is sorted, so we can stop looking. + break; + } + if ($status->getDateFrom() < $epoch_end && + $status->getDateTo() > $epoch_start) { + $timespan = $status->getDateTo() - $status->getDateFrom(); + if ($timespan > $one_day) { + $time_str = 'm/d'; + } else { + $time_str = 'h:i A'; + } + $epoch_range = phabricator_format_local_time( + $status->getDateFrom(), + $user, + $time_str + ) . ' - ' . phabricator_format_local_time( + $status->getDateTo(), + $user, + $time_str + ); + + $content[] = phutil_tag( + 'div', + array( + 'class' => 'user-status '.$status->getTextStatus(), + ), + array( + phutil_tag( + 'div', + array( + 'class' => 'epoch-range' + ), + $epoch_range + ), + phutil_tag( + 'div', + array( + 'class' => 'icon', + ), + '' + ), + phutil_tag( + 'div', + array( + 'class' => 'description' + ), + $status->getTerseSummary($user) + ), + phutil_tag( + 'div', + array( + 'class' => 'participant' + ), + $handles[$status->getUserPHID()]->getName() + ) + ) + ); + } + } + } + + return new PhutilSafeHTML(implode('', $content)); + } + + private function getCalendarWidgetWeekTimestamps() { + $user = $this->getRequest()->getUser(); + $timezone = new DateTimeZone($user->getTimezoneIdentifier()); + + $timestamps = array(); + for ($day = 0; $day < 7; $day++) { + $timestamps[] = new DateTime( + sprintf('today +%d days', $day), + $timezone + ); + } + + return $timestamps; } } diff --git a/src/applications/conpherence/query/ConpherenceThreadQuery.php b/src/applications/conpherence/query/ConpherenceThreadQuery.php index 18fc8ec1b5..d22fd03820 100644 --- a/src/applications/conpherence/query/ConpherenceThreadQuery.php +++ b/src/applications/conpherence/query/ConpherenceThreadQuery.php @@ -141,17 +141,22 @@ final class ConpherenceThreadQuery $tasks = mgroup($tasks, 'getOwnerPHID'); // statuses of everyone currently in the conpherence - // until the beginning of the next work week. - // NOTE: this is a bit boring on the weekends. + // for a rolling one week window + $start_of_week = phabricator_format_local_time( + strtotime('today'), + $this->getViewer(), + 'U' + ); $end_of_week = phabricator_format_local_time( - strtotime('Monday midnight'), + strtotime('midnight +1 week'), $this->getViewer(), 'U' ); $statuses = id(new PhabricatorUserStatus()) ->loadAllWhere( - 'userPHID in (%Ls) AND dateTo <= %d', + 'userPHID in (%Ls) AND dateTo >= %d AND dateFrom <= %d', $participant_phids, + $start_of_week, $end_of_week ); $statuses = mgroup($statuses, 'getUserPHID'); @@ -168,9 +173,12 @@ final class ConpherenceThreadQuery foreach ($conpherences as $phid => $conpherence) { $participant_phids = array_keys($conpherence->getParticipants()); + $statuses = array_select_keys($statuses, $participant_phids); + $statuses = array_mergev($statuses); + $statuses = msort($statuses, 'getDateFrom'); $widget_data = array( 'tasks' => array_select_keys($tasks, $participant_phids), - 'statuses' => array_select_keys($statuses, $participant_phids), + 'statuses' => $statuses, 'files' => array_select_keys($files, $conpherence->getFilePHIDs()), ); $conpherence->attachWidgetData($widget_data); diff --git a/src/applications/conpherence/view/ConpherenceMenuItemView.php b/src/applications/conpherence/view/ConpherenceMenuItemView.php index b2e7cbccd0..6cc4d7a88a 100644 --- a/src/applications/conpherence/view/ConpherenceMenuItemView.php +++ b/src/applications/conpherence/view/ConpherenceMenuItemView.php @@ -85,7 +85,7 @@ final class ConpherenceMenuItemView extends AphrontTagView { protected function getTagContent() { $image = null; if ($this->imageURI) { - $image = phutil_render_tag( + $image = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-image', @@ -95,34 +95,34 @@ final class ConpherenceMenuItemView extends AphrontTagView { } $title = null; if ($this->title) { - $title = phutil_render_tag( + $title = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-title', ), - phutil_escape_html($this->title)); + $this->title); } $subtitle = null; if ($this->subtitle) { - $subtitle = phutil_render_tag( + $subtitle = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-subtitle', ), - phutil_escape_html($this->subtitle)); + $this->subtitle); } $message = null; if ($this->messageText) { - $message = phutil_render_tag( + $message = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-message-text' ), - phutil_escape_html($this->messageText)); + $this->messageText); } $epoch = null; if ($this->epoch) { - $epoch = phutil_render_tag( + $epoch = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-date', @@ -131,7 +131,7 @@ final class ConpherenceMenuItemView extends AphrontTagView { } $unread_count = null; if ($this->unreadCount) { - $unread_count = phutil_render_tag( + $unread_count = phutil_tag( 'span', array( 'class' => 'conpherence-menu-item-unread-count' diff --git a/src/applications/conpherence/view/ConpherenceTransactionView.php b/src/applications/conpherence/view/ConpherenceTransactionView.php index d60f648414..d8163b3ecd 100644 --- a/src/applications/conpherence/view/ConpherenceTransactionView.php +++ b/src/applications/conpherence/view/ConpherenceTransactionView.php @@ -47,7 +47,7 @@ final class ConpherenceTransactionView extends AphrontView { case ConpherenceTransactionType::TYPE_PICTURE: $img = $transaction->getHandle($transaction->getNewValue()); $content = $transaction->getTitle() . - phutil_render_tag( + phutil_tag( 'img', array( 'src' => $img->getImageURI() @@ -85,12 +85,12 @@ final class ConpherenceTransactionView extends AphrontView { } $transaction_view - ->appendChild(phutil_render_tag( + ->appendChild(phutil_tag( 'div', array( 'class' => $content_class ), - $content) + new PhutilSafeHTML($content)) ); return $transaction_view->render(); diff --git a/webroot/rsrc/css/application/conpherence/widget-pane.css b/webroot/rsrc/css/application/conpherence/widget-pane.css index 224adc2db5..6cc2c4b19e 100644 --- a/webroot/rsrc/css/application/conpherence/widget-pane.css +++ b/webroot/rsrc/css/application/conpherence/widget-pane.css @@ -12,9 +12,88 @@ border-color: #CCC; border-style: solid; background: url('/rsrc/image/texture/dust_background.jpg'); + overflow-y: auto; } .conpherence-widget-pane .aphront-form-input { margin: 0; width: 100%; } + +.conpherence-widget-pane .widgets-header { + height: 40px; + width: 127px; + margin: 0px auto 0px auto; +} + +.conpherence-widget-pane .widgets-header .sprite-conpher { + display: block; + width: 29px; + height: 33px; + margin: 4px 0px 0px 20px; + float: left; + clear: none; +} +.conpherence-widget-pane .widgets-header .first-icon { + margin-left: 0px; +} + +.conpherence-widget-pane .widgets-body { + position: fixed; + overflow-y: auto; + top: 165px; + bottom: 0px; + width: 320px; +} + +/* calendar widget */ + +.conpherence-widget-pane #widgets-calendar { +} + +.conpherence-widget-pane #widgets-calendar .user-status { + height: 60px; +} + +.conpherence-widget-pane #widgets-calendar .user-status .icon { + border-radius: 10px; + position: relative; + top: 24px; + left: 12px; + height: 16px; + width: 16px; + box-shadow: 0px 0px 1px #000; +} + +.conpherence-widget-pane #widgets-calendar .sporadic .icon { + background-color: rgb(222, 226, 232); +} + +.conpherence-widget-pane #widgets-calendar .away .icon { + background-color: rgb(102, 204, 255); +} + +.conpherence-widget-pane #widgets-calendar .user-status .epoch-range { + float: right; + font-style: italic; + position: relative; + top: 24px; + right: 8px; + font-size: 11px; +} + +.conpherence-widget-pane #widgets-calendar .user-status .description { + position: relative; + left: 40px; + top: 0px; + width: 260px; +} + +.conpherence-widget-pane #widgets-calendar .user-status .participant { + position: relative; + left: 40px; + top: 0px; + font-style: italic; + font-size: 11px; + width: 260px; +} diff --git a/webroot/rsrc/css/sprite-conph.css b/webroot/rsrc/css/sprite-conph.css index d11ae477c5..8f2d3cdec1 100644 --- a/webroot/rsrc/css/sprite-conph.css +++ b/webroot/rsrc/css/sprite-conph.css @@ -4,7 +4,7 @@ */ .sprite-conpher { - background-image: url(/rsrc/image/sprite-conpher.png); + background-image: url(/rsrc/image/sprite-conph.png); background-repeat: no-repeat; } @@ -12,7 +12,7 @@ only screen and (min-device-pixel-ratio: 1.5), only screen and (-webkit-min-device-pixel-ratio: 1.5) { .sprite-conpher { - background-image: url(/rsrc/image/sprite-conpher-X2.png); + background-image: url(/rsrc/image/sprite-conph-X2.png); background-size: 132px 132px; } } diff --git a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js index badbe128f6..00def66f7c 100644 --- a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js +++ b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js @@ -16,8 +16,15 @@ JX.behavior('conpherence-widget-pane', function(config) { for (var widget in config.widgetRegistery) { if (widget == data.widget) { JX.$(widget).style.display = 'block'; + JX.DOM.alterClass(e.getTarget(), data.toggleClass, true); } else { JX.$(widget).style.display = 'none'; + var cur_toggle = JX.$(widget + '-toggle'); + JX.DOM.alterClass( + cur_toggle, + JX.Stratcom.getData(cur_toggle).toggleClass, + false + ); } } } From e4a0c170799c16f8c129ff8e768b7faaf892f103 Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Mon, 4 Feb 2013 19:05:50 -0800 Subject: [PATCH 12/13] fix Conpherence sorting Summary: this broke when I moved sorting to the editor. Turns out you can't have custom hooks for the comment transaction, and thus I couldn't update participation inside the editor. This fixes this by removing the empty switch statement for the transaction type inside the parent class editor. This should have no effect other than fixing Conpherence. Note that conpherences will need another message, etc for a given conphernece to fix itself. Test Plan: Conpherence threads were updated properly! Reviewers: epriestley Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T2399 Differential Revision: https://secure.phabricator.com/D4817 --- .../editor/PhabricatorApplicationTransactionEditor.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index 7a3d07fd77..349bb3c453 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -153,25 +153,20 @@ abstract class PhabricatorApplicationTransactionEditor PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { - case PhabricatorTransactions::TYPE_COMMENT: - break; case PhabricatorTransactions::TYPE_VIEW_POLICY: $object->setViewPolicy($xaction->getNewValue()); break; case PhabricatorTransactions::TYPE_EDIT_POLICY: $object->setEditPolicy($xaction->getNewValue()); break; - default: - return $this->applyCustomInternalTransaction($object, $xaction); } + return $this->applyCustomInternalTransaction($object, $xaction); } private function applyExternalEffects( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { - case PhabricatorTransactions::TYPE_COMMENT: - break; case PhabricatorTransactions::TYPE_SUBSCRIBERS: $subeditor = id(new PhabricatorSubscriptionsEditor()) ->setObject($object) @@ -179,9 +174,8 @@ abstract class PhabricatorApplicationTransactionEditor ->subscribeExplicit($xaction->getNewValue()) ->save(); break; - default: - return $this->applyCustomExternalTransaction($object, $xaction); } + return $this->applyCustomExternalTransaction($object, $xaction); } protected function applyCustomInternalTransaction( From 742ee44960b0b9eadb7b72ddbfc9dbb435bf2dca Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 5 Feb 2013 07:43:58 -0800 Subject: [PATCH 13/13] Fix show/hide applications on homepage Summary: Fixes T2482. After D4792, menus have more formal structure, but previously we were just shoving some `
` into the middle of the thing. This no longer works correctly, since we end up with `
`. Just put IDs on all the items we're going to show/hide instead so we don't have to render any half-tags. Test Plan: Home page show/hide works again. Reviewers: btrahan, chad Reviewed By: btrahan CC: aran Maniphest Tasks: T2482 Differential Revision: https://secure.phabricator.com/D4810 --- src/__celerity_resource_map__.php | 130 ++++++++---------- .../PhabricatorDirectoryController.php | 38 +++-- .../core/behavior-home-reveal-tiles.js | 8 +- 3 files changed, 90 insertions(+), 86 deletions(-) diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 7693a108a5..7d4df11a0b 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -1292,7 +1292,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-differential-keyboard-navigation' => array( - 'uri' => '/res/89e93cc9/rsrc/js/application/differential/behavior-keyboard-nav.js', + 'uri' => '/res/a7798465/rsrc/js/application/differential/behavior-keyboard-nav.js', 'type' => 'js', 'requires' => array( @@ -1664,21 +1664,9 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/application/core/behavior-autofocus.js', ), - 'javelin-behavior-phabricator-file-tree' => - array( - 'uri' => '/res/e9c96597/rsrc/js/application/core/behavior-file-tree.js', - 'type' => 'js', - 'requires' => - array( - 0 => 'javelin-behavior', - 1 => 'phabricator-keyboard-shortcut', - 2 => 'javelin-stratcom', - ), - 'disk' => '/rsrc/js/application/core/behavior-file-tree.js', - ), 'javelin-behavior-phabricator-home-reveal-tiles' => array( - 'uri' => '/res/7230ca0c/rsrc/js/application/core/behavior-home-reveal-tiles.js', + 'uri' => '/res/b3c5cea9/rsrc/js/application/core/behavior-home-reveal-tiles.js', 'type' => 'js', 'requires' => array( @@ -1716,7 +1704,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-phabricator-nav' => array( - 'uri' => '/res/222b9329/rsrc/js/application/core/behavior-phabricator-nav.js', + 'uri' => '/res/cec31f3f/rsrc/js/application/core/behavior-phabricator-nav.js', 'type' => 'js', 'requires' => array( @@ -3443,7 +3431,7 @@ celerity_register_resource_map(array( 'uri' => '/res/pkg/7d347135/core.pkg.css', 'type' => 'css', ), - '22373a47' => + 'd2e59a7e' => array( 'name' => 'core.pkg.js', 'symbols' => @@ -3482,7 +3470,7 @@ celerity_register_resource_map(array( 31 => 'javelin-behavior-global-drag-and-drop', 32 => 'javelin-behavior-phabricator-home-reveal-tiles', ), - 'uri' => '/res/pkg/22373a47/core.pkg.js', + 'uri' => '/res/pkg/d2e59a7e/core.pkg.js', 'type' => 'js', ), '8edbada5' => @@ -3520,7 +3508,7 @@ celerity_register_resource_map(array( 'uri' => '/res/pkg/ec01d039/differential.pkg.css', 'type' => 'css', ), - '95d0d865' => + '1b2c991b' => array( 'name' => 'differential.pkg.js', 'symbols' => @@ -3545,7 +3533,7 @@ celerity_register_resource_map(array( 17 => 'javelin-behavior-differential-toggle-files', 18 => 'javelin-behavior-differential-user-select', ), - 'uri' => '/res/pkg/95d0d865/differential.pkg.js', + 'uri' => '/res/pkg/1b2c991b/differential.pkg.js', 'type' => 'js', ), 'c8ce2d88' => @@ -3645,7 +3633,7 @@ celerity_register_resource_map(array( 'aphront-typeahead-control-css' => '7d347135', 'differential-changeset-view-css' => 'ec01d039', 'differential-core-view-css' => 'ec01d039', - 'differential-inline-comment-editor' => '95d0d865', + 'differential-inline-comment-editor' => '1b2c991b', 'differential-local-commits-view-css' => 'ec01d039', 'differential-results-table-css' => 'ec01d039', 'differential-revision-add-comment-css' => 'ec01d039', @@ -3658,56 +3646,56 @@ celerity_register_resource_map(array( 'diffusion-icons-css' => 'c8ce2d88', 'global-drag-and-drop-css' => '7d347135', 'inline-comment-summary-css' => 'ec01d039', - 'javelin-aphlict' => '22373a47', + 'javelin-aphlict' => 'd2e59a7e', 'javelin-behavior' => '88225b70', - 'javelin-behavior-aphlict-dropdown' => '22373a47', - 'javelin-behavior-aphlict-listen' => '22373a47', - 'javelin-behavior-aphront-basic-tokenizer' => '22373a47', - 'javelin-behavior-aphront-drag-and-drop' => '95d0d865', - 'javelin-behavior-aphront-drag-and-drop-textarea' => '95d0d865', - 'javelin-behavior-aphront-form-disable-on-submit' => '22373a47', + 'javelin-behavior-aphlict-dropdown' => 'd2e59a7e', + 'javelin-behavior-aphlict-listen' => 'd2e59a7e', + 'javelin-behavior-aphront-basic-tokenizer' => 'd2e59a7e', + 'javelin-behavior-aphront-drag-and-drop' => '1b2c991b', + 'javelin-behavior-aphront-drag-and-drop-textarea' => '1b2c991b', + 'javelin-behavior-aphront-form-disable-on-submit' => 'd2e59a7e', 'javelin-behavior-audit-preview' => 'f96657b8', 'javelin-behavior-dark-console' => '8edbada5', 'javelin-behavior-dark-console-ajax' => '8edbada5', - 'javelin-behavior-device' => '22373a47', - 'javelin-behavior-differential-accept-with-errors' => '95d0d865', - 'javelin-behavior-differential-add-reviewers-and-ccs' => '95d0d865', - 'javelin-behavior-differential-comment-jump' => '95d0d865', - 'javelin-behavior-differential-diff-radios' => '95d0d865', - 'javelin-behavior-differential-dropdown-menus' => '95d0d865', - 'javelin-behavior-differential-edit-inline-comments' => '95d0d865', - 'javelin-behavior-differential-feedback-preview' => '95d0d865', - 'javelin-behavior-differential-keyboard-navigation' => '95d0d865', - 'javelin-behavior-differential-populate' => '95d0d865', - 'javelin-behavior-differential-show-more' => '95d0d865', - 'javelin-behavior-differential-toggle-files' => '95d0d865', - 'javelin-behavior-differential-user-select' => '95d0d865', + 'javelin-behavior-device' => 'd2e59a7e', + 'javelin-behavior-differential-accept-with-errors' => '1b2c991b', + 'javelin-behavior-differential-add-reviewers-and-ccs' => '1b2c991b', + 'javelin-behavior-differential-comment-jump' => '1b2c991b', + 'javelin-behavior-differential-diff-radios' => '1b2c991b', + 'javelin-behavior-differential-dropdown-menus' => '1b2c991b', + 'javelin-behavior-differential-edit-inline-comments' => '1b2c991b', + 'javelin-behavior-differential-feedback-preview' => '1b2c991b', + 'javelin-behavior-differential-keyboard-navigation' => '1b2c991b', + 'javelin-behavior-differential-populate' => '1b2c991b', + 'javelin-behavior-differential-show-more' => '1b2c991b', + 'javelin-behavior-differential-toggle-files' => '1b2c991b', + 'javelin-behavior-differential-user-select' => '1b2c991b', 'javelin-behavior-diffusion-commit-graph' => 'f96657b8', 'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8', 'javelin-behavior-error-log' => '8edbada5', - 'javelin-behavior-global-drag-and-drop' => '22373a47', - 'javelin-behavior-konami' => '22373a47', - 'javelin-behavior-lightbox-attachments' => '22373a47', + 'javelin-behavior-global-drag-and-drop' => 'd2e59a7e', + 'javelin-behavior-konami' => 'd2e59a7e', + 'javelin-behavior-lightbox-attachments' => 'd2e59a7e', 'javelin-behavior-maniphest-batch-selector' => '7707de41', 'javelin-behavior-maniphest-subpriority-editor' => '7707de41', 'javelin-behavior-maniphest-transaction-controls' => '7707de41', 'javelin-behavior-maniphest-transaction-expand' => '7707de41', 'javelin-behavior-maniphest-transaction-preview' => '7707de41', - 'javelin-behavior-phabricator-active-nav' => '22373a47', - 'javelin-behavior-phabricator-autofocus' => '22373a47', - 'javelin-behavior-phabricator-home-reveal-tiles' => '22373a47', - 'javelin-behavior-phabricator-keyboard-shortcuts' => '22373a47', - 'javelin-behavior-phabricator-nav' => '22373a47', - 'javelin-behavior-phabricator-object-selector' => '95d0d865', - 'javelin-behavior-phabricator-oncopy' => '22373a47', - 'javelin-behavior-phabricator-remarkup-assist' => '22373a47', - 'javelin-behavior-phabricator-search-typeahead' => '22373a47', - 'javelin-behavior-phabricator-tooltips' => '22373a47', - 'javelin-behavior-phabricator-watch-anchor' => '22373a47', - 'javelin-behavior-refresh-csrf' => '22373a47', - 'javelin-behavior-repository-crossreference' => '95d0d865', - 'javelin-behavior-toggle-class' => '22373a47', - 'javelin-behavior-workflow' => '22373a47', + 'javelin-behavior-phabricator-active-nav' => 'd2e59a7e', + 'javelin-behavior-phabricator-autofocus' => 'd2e59a7e', + 'javelin-behavior-phabricator-home-reveal-tiles' => 'd2e59a7e', + 'javelin-behavior-phabricator-keyboard-shortcuts' => 'd2e59a7e', + 'javelin-behavior-phabricator-nav' => 'd2e59a7e', + 'javelin-behavior-phabricator-object-selector' => '1b2c991b', + 'javelin-behavior-phabricator-oncopy' => 'd2e59a7e', + 'javelin-behavior-phabricator-remarkup-assist' => 'd2e59a7e', + 'javelin-behavior-phabricator-search-typeahead' => 'd2e59a7e', + 'javelin-behavior-phabricator-tooltips' => 'd2e59a7e', + 'javelin-behavior-phabricator-watch-anchor' => 'd2e59a7e', + 'javelin-behavior-refresh-csrf' => 'd2e59a7e', + 'javelin-behavior-repository-crossreference' => '1b2c991b', + 'javelin-behavior-toggle-class' => 'd2e59a7e', + 'javelin-behavior-workflow' => 'd2e59a7e', 'javelin-dom' => '88225b70', 'javelin-event' => '88225b70', 'javelin-install' => '88225b70', @@ -3729,39 +3717,39 @@ celerity_register_resource_map(array( 'lightbox-attachment-css' => '7d347135', 'maniphest-task-summary-css' => 'e30a3fa8', 'maniphest-transaction-detail-css' => 'e30a3fa8', - 'phabricator-busy' => '22373a47', + 'phabricator-busy' => 'd2e59a7e', 'phabricator-content-source-view-css' => 'ec01d039', 'phabricator-core-buttons-css' => '7d347135', 'phabricator-core-css' => '7d347135', 'phabricator-crumbs-view-css' => '7d347135', 'phabricator-directory-css' => '7d347135', - 'phabricator-drag-and-drop-file-upload' => '95d0d865', - 'phabricator-dropdown-menu' => '22373a47', - 'phabricator-file-upload' => '22373a47', + 'phabricator-drag-and-drop-file-upload' => '1b2c991b', + 'phabricator-dropdown-menu' => 'd2e59a7e', + 'phabricator-file-upload' => 'd2e59a7e', 'phabricator-filetree-view-css' => '7d347135', 'phabricator-flag-css' => '7d347135', 'phabricator-form-view-css' => '7d347135', 'phabricator-header-view-css' => '7d347135', 'phabricator-jump-nav' => '7d347135', - 'phabricator-keyboard-shortcut' => '22373a47', - 'phabricator-keyboard-shortcut-manager' => '22373a47', + 'phabricator-keyboard-shortcut' => 'd2e59a7e', + 'phabricator-keyboard-shortcut-manager' => 'd2e59a7e', 'phabricator-main-menu-view' => '7d347135', - 'phabricator-menu-item' => '22373a47', + 'phabricator-menu-item' => 'd2e59a7e', 'phabricator-nav-view-css' => '7d347135', - 'phabricator-notification' => '22373a47', + 'phabricator-notification' => 'd2e59a7e', 'phabricator-notification-css' => '7d347135', 'phabricator-notification-menu-css' => '7d347135', 'phabricator-object-item-list-view-css' => '7d347135', 'phabricator-object-selector-css' => 'ec01d039', - 'phabricator-paste-file-upload' => '22373a47', - 'phabricator-prefab' => '22373a47', + 'phabricator-paste-file-upload' => 'd2e59a7e', + 'phabricator-prefab' => 'd2e59a7e', 'phabricator-project-tag-css' => 'e30a3fa8', 'phabricator-remarkup-css' => '7d347135', - 'phabricator-shaped-request' => '95d0d865', + 'phabricator-shaped-request' => '1b2c991b', 'phabricator-side-menu-view-css' => '7d347135', 'phabricator-standard-page-view' => '7d347135', - 'phabricator-textareautils' => '22373a47', - 'phabricator-tooltip' => '22373a47', + 'phabricator-textareautils' => 'd2e59a7e', + 'phabricator-tooltip' => 'd2e59a7e', 'phabricator-transaction-view-css' => '7d347135', 'phabricator-zindex-css' => '7d347135', 'sprite-apps-large-css' => '7d347135', diff --git a/src/applications/directory/controller/PhabricatorDirectoryController.php b/src/applications/directory/controller/PhabricatorDirectoryController.php index 293ead040f..a5bff704f5 100644 --- a/src/applications/directory/controller/PhabricatorDirectoryController.php +++ b/src/applications/directory/controller/PhabricatorDirectoryController.php @@ -79,7 +79,7 @@ abstract class PhabricatorDirectoryController extends PhabricatorController { $is_hide = ($tile_display == PhabricatorApplication::TILE_HIDE); if ($is_hide) { $show_item_id = celerity_generate_unique_node_id(); - $show_tiles_id = celerity_generate_unique_node_id(); + $hide_item_id = celerity_generate_unique_node_id(); $show_item = id(new PhabricatorMenuItemView()) ->setName(pht('Show More Applications')) @@ -90,18 +90,12 @@ abstract class PhabricatorDirectoryController extends PhabricatorController { $hide_item = id(new PhabricatorMenuItemView()) ->setName(pht('Show Fewer Applications')) ->setHref('#') + ->setStyle('display: none') + ->setID($hide_item_id) ->addSigil('home-hide-applications'); $nav->addMenuItem($show_item); - $nav->addCustomBlock( - '
'); - - Javelin::initBehavior('phabricator-home-reveal-tiles', array( - 'tilesID' => $show_tiles_id, - 'showID' => $show_item_id, - )); + $tile_ids = array($hide_item_id); } foreach ($tile_group as $group => $application_list) { @@ -124,21 +118,39 @@ abstract class PhabricatorDirectoryController extends PhabricatorController { while (count($tiles) % 3) { $tiles[] = id(new PhabricatorApplicationLaunchView()); } - $nav->addLabel($groups[$group]); + $label = id(new PhabricatorMenuItemView()) + ->setType(PhabricatorMenuItemView::TYPE_LABEL) + ->setName($groups[$group]); + + if ($is_hide) { + $label->setStyle('display: none'); + $label_id = celerity_generate_unique_node_id(); + $label->setID($label_id); + $tile_ids[] = $label_id; + } + + $nav->addMenuItem($label); } + + $group_id = celerity_generate_unique_node_id(); + $tile_ids[] = $group_id; $nav->addCustomBlock( phutil_render_tag( 'div', array( 'class' => 'application-tile-group', + 'id' => $group_id, + 'style' => ($is_hide ? 'display: none' : null), ), id(new AphrontNullView())->appendChild($tiles)->render())); } - $is_hide = ($tile_display == PhabricatorApplication::TILE_HIDE); if ($is_hide) { + Javelin::initBehavior('phabricator-home-reveal-tiles', array( + 'tileIDs' => $tile_ids, + 'showID' => $show_item_id, + )); $nav->addMenuItem($hide_item); - $nav->addCustomBlock('
'); } } diff --git a/webroot/rsrc/js/application/core/behavior-home-reveal-tiles.js b/webroot/rsrc/js/application/core/behavior-home-reveal-tiles.js index 14d77841e8..b94e3fbd41 100644 --- a/webroot/rsrc/js/application/core/behavior-home-reveal-tiles.js +++ b/webroot/rsrc/js/application/core/behavior-home-reveal-tiles.js @@ -13,7 +13,9 @@ JX.behavior('phabricator-home-reveal-tiles', function(config) { function(e) { e.kill(); - JX.DOM.show(JX.$(config.tilesID)); + for (var ii = 0; ii < config.tileIDs.length; ii++) { + JX.DOM.show(JX.$(config.tileIDs[ii])); + } JX.DOM.hide(JX.$(config.showID)); }); @@ -23,7 +25,9 @@ JX.behavior('phabricator-home-reveal-tiles', function(config) { function(e) { e.kill(); - JX.DOM.hide(JX.$(config.tilesID)); + for (var ii = 0; ii < config.tileIDs.length; ii++) { + JX.DOM.hide(JX.$(config.tileIDs[ii])); + } JX.DOM.show(JX.$(config.showID)); }); });