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/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/__phutil_library_map__.php b/src/__phutil_library_map__.php index f587f31e17..c9e7a4dd43 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1226,6 +1226,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', @@ -2625,6 +2626,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/config/check/PhabricatorSetupCheckDatabase.php b/src/applications/config/check/PhabricatorSetupCheckDatabase.php index d966b19b97..b4e19e2a0f 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'); diff --git a/src/applications/conpherence/controller/ConpherenceListController.php b/src/applications/conpherence/controller/ConpherenceListController.php index 46bae21db9..31a00ba670 100644 --- a/src/applications/conpherence/controller/ConpherenceListController.php +++ b/src/applications/conpherence/controller/ConpherenceListController.php @@ -77,15 +77,17 @@ final class ConpherenceListController extends 'class' => 'conpherence-header-pane', 'id' => 'conpherence-header-pane', ), - ''), + '' + ), phutil_tag( 'div', array( 'class' => 'conpherence-widget-pane', 'id' => 'conpherence-widget-pane' ), - ''), - phutil_tag( + '' + ), + javelin_tag( 'div', array( 'class' => 'conpherence-message-pane', @@ -98,15 +100,19 @@ final class ConpherenceListController extends '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 dff27bcf9a..21616a4978 100644 --- a/src/applications/conpherence/controller/ConpherenceNewController.php +++ b/src/applications/conpherence/controller/ConpherenceNewController.php @@ -95,8 +95,7 @@ final class ConpherenceNewController extends ConpherenceController { phutil_tag( 'p', array(), - pht('Message sent successfully.')) - ); + pht('Message sent successfully.'))); $response = id(new AphrontDialogResponse()) ->setDialog($dialog); } else { diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php index 742df97250..e272f871f3 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,7 +166,7 @@ final class ConpherenceViewController extends $conpherence = $this->getConpherence(); - $widgets = phutil_render_tag( + $widgets = phutil_tag( 'div', array( 'class' => 'widgets-header' @@ -175,31 +176,44 @@ final class ConpherenceViewController extends 'a', array( 'sigil' => 'conpherence-change-widget', - 'meta' => array('widget' => 'widgets-files') + 'meta' => array( + 'widget' => 'widgets-files', + 'toggleClass' => 'conpher_files_on' + ), + 'id' => 'widgets-files-toggle', + 'class' => 'sprite-conpher conpher_files_off first-icon' ), - pht('Files') + '' ), - ' | ', javelin_tag( 'a', array( 'sigil' => 'conpherence-change-widget', - 'meta' => array('widget' => 'widgets-tasks') + '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_tag( 'a', array( 'sigil' => 'conpherence-change-widget', - 'meta' => array('widget' => 'widgets-calendar') + 'meta' => array( + 'widget' => 'widgets-calendar', + 'toggleClass' => 'conpher_calendar_on' + ), + 'id' => 'widgets-calendar-toggle', + 'class' => 'sprite-conpher conpher_calendar_off', ), - pht('Calendar') - ), + '' + ) ) ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'widgets-body', @@ -208,7 +222,7 @@ final class ConpherenceViewController extends ), $this->renderFilesWidgetPaneContent() ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'widgets-body', @@ -216,7 +230,7 @@ final class ConpherenceViewController extends ), $this->renderTaskWidgetPaneContent() ). - phutil_render_tag( + phutil_tag( 'div', array( 'class' => 'widgets-body', @@ -253,7 +267,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() { @@ -279,7 +293,8 @@ final class ConpherenceViewController extends array( 'href' => '/T'.$task->getID() ), - $task->getTitle()), + $task->getTitle() + ) ); } $table = id(new AphrontTableView($data)) @@ -288,13 +303,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/ConpherenceTransactionView.php b/src/applications/conpherence/view/ConpherenceTransactionView.php index bcb3278fa7..7e6c842526 100644 --- a/src/applications/conpherence/view/ConpherenceTransactionView.php +++ b/src/applications/conpherence/view/ConpherenceTransactionView.php @@ -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/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php index c48883d6ed..5dc9211297 100644 --- a/src/applications/differential/controller/DifferentialRevisionViewController.php +++ b/src/applications/differential/controller/DifferentialRevisionViewController.php @@ -408,29 +408,42 @@ final class DifferentialRevisionViewController extends DifferentialController { ->setAnchorName('top') ->setNavigationMarker(true); - $nav = id(new DifferentialChangesetFileTreeSideNavBuilder()) - ->setAnchorName('top') - ->setTitle('D'.$revision->getID()) - ->setBaseURI(new PhutilURI('/D'.$revision->getID())) - ->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/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/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php b/src/applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php index f2b1e59f40..acfc3a7a88 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(); @@ -123,6 +130,8 @@ final class DifferentialChangesetFileTreeSideNavBuilder { ), $filetree); + Javelin::initBehavior('phabricator-file-tree', array()); + $nav->addLabel(pht('Changed Files')); $nav->addCustomBlock($filetree); $nav->setActive(true); diff --git a/src/applications/differential/view/DifferentialChangesetListView.php b/src/applications/differential/view/DifferentialChangesetListView.php index 11209f000c..8021859aff 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 fa7686699e..93caaab144 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/diffusion/controller/DiffusionCommitController.php b/src/applications/diffusion/controller/DiffusionCommitController.php index bb6ac15f3e..65e47e3af1 100644 --- a/src/applications/diffusion/controller/DiffusionCommitController.php +++ b/src/applications/diffusion/controller/DiffusionCommitController.php @@ -327,13 +327,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/directory/controller/PhabricatorDirectoryController.php b/src/applications/directory/controller/PhabricatorDirectoryController.php index b7064d4360..11a47d7014 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( - hsprintf( - '')); } } 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/maniphest/controller/ManiphestTaskListController.php b/src/applications/maniphest/controller/ManiphestTaskListController.php index a51951a4de..3f89a567a6 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('
'); 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/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/panel/PhabricatorSettingsPanelDisplayPreferences.php b/src/applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php index c6bc086e0f..9c77817262 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/panel/PhabricatorSettingsPanelProfile.php b/src/applications/settings/panel/PhabricatorSettingsPanelProfile.php index 0ade8c291a..358ab27438 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') diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php index 4338e1ef61..9f5196a215 100644 --- a/src/applications/settings/storage/PhabricatorUserPreferences.php +++ b/src/applications/settings/storage/PhabricatorUserPreferences.php @@ -18,11 +18,13 @@ 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_COLLAPSED = 'nav-collapsed'; 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/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( diff --git a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php index db784f1169..eb048f8c4c 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( 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'), + ), ); } diff --git a/src/view/form/control/AphrontFormImageControl.php b/src/view/form/control/AphrontFormImageControl.php index 0953eabbf1..ba2adb2c92 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_tag( diff --git a/src/view/form/control/PhabricatorRemarkupControl.php b/src/view/form/control/PhabricatorRemarkupControl.php index e1faf1dfb3..42b5d143b8 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') { diff --git a/src/view/layout/AphrontSideNavFilterView.php b/src/view/layout/AphrontSideNavFilterView.php index 8c0fe5a7c6..ffbe0ca0bc 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_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_tag( 'div', @@ -243,7 +251,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', @@ -253,6 +263,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/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; } 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 + ); } } } 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/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)); }); }); 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(); }); 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)