mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-28 16:30:59 +01:00
Merge branch 'master' into phutil_tag
(Final sync.)
This commit is contained in:
commit
8f1311bbc1
41 changed files with 589 additions and 201 deletions
|
@ -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
|
||||
|
|
33
resources/sql/patches/20130201.revisionunsubscribed.php
Normal file
33
resources/sql/patches/20130201.revisionunsubscribed.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
echo "Migrating Differential unsubscribed users to edges...\n";
|
||||
$table = new DifferentialRevision();
|
||||
$table->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";
|
2
resources/sql/patches/20130201.revisionunsubscribed.sql
Normal file
2
resources/sql/patches/20130201.revisionunsubscribed.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_differential.differential_revision
|
||||
DROP unsubscribed;
|
|
@ -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',
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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'
|
||||
),
|
||||
''),
|
||||
)),
|
||||
));
|
||||
''
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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(),
|
||||
));
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
'<div id="%s" style="display: none;">',
|
||||
$show_tiles_id));
|
||||
|
||||
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,22 +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_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'application-tile-group',
|
||||
'id' => $group_id,
|
||||
'style' => ($is_hide ? 'display: none' : null),
|
||||
),
|
||||
mpull($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(hsprintf('</div>'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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('<div class="maniphest-group-container">');
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -133,6 +133,7 @@ final class PhamePostEditController
|
|||
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
|
||||
->setID('post-body')
|
||||
->setUser($user)
|
||||
->setDisableMacros(true)
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSettingsPanelDiffPreferences
|
||||
extends PhabricatorSettingsPanel {
|
||||
|
||||
public function getPanelKey() {
|
||||
return 'diff';
|
||||
}
|
||||
|
||||
public function getPanelName() {
|
||||
return pht('Diff Preferences');
|
||||
}
|
||||
|
||||
public function getPanelGroup() {
|
||||
return pht('Application Settings');
|
||||
}
|
||||
|
||||
public function processRequest(AphrontRequest $request) {
|
||||
$user = $request->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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
|||
'<pre class="PhabricatorMonospaced">'.
|
||||
phutil_escape_html($example_string).
|
||||
'</pre>'))
|
||||
->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')
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ final class AphrontFormImageControl extends AphrontFormControl {
|
|||
array(
|
||||
'type' => 'file',
|
||||
'name' => $this->getName(),
|
||||
'class' => 'image',
|
||||
)).
|
||||
'<div style="clear: both;">'.
|
||||
phutil_tag(
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl {
|
||||
|
||||
private $disableMacro = false;
|
||||
public function setDisableMacros($disable) {
|
||||
$this->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') {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
webroot/rsrc/js/application/core/behavior-file-tree.js
Normal file
16
webroot/rsrc/js/application/core/behavior-file-tree.js
Normal file
|
@ -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();
|
||||
|
||||
});
|
|
@ -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));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue