mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-04 20:01:00 +01:00
Merge branch 'master' into redesign
This commit is contained in:
commit
09a3506821
83 changed files with 820 additions and 492 deletions
|
@ -992,6 +992,7 @@ return array(
|
|||
'bash' => 'Bash Scripting',
|
||||
'brainfuck' => 'Brainf*ck',
|
||||
'c' => 'C',
|
||||
'coffee-script' => 'CoffeeScript',
|
||||
'cpp' => 'C++',
|
||||
'css' => 'CSS',
|
||||
'd' => 'D',
|
||||
|
@ -999,14 +1000,18 @@ return array(
|
|||
'django' => 'Django Templating',
|
||||
'erb' => 'Embedded Ruby/ERB',
|
||||
'erlang' => 'Erlang',
|
||||
'go' => 'Golang',
|
||||
'groovy' => 'Groovy',
|
||||
'haskell' => 'Haskell',
|
||||
'html' => 'HTML',
|
||||
'java' => 'Java',
|
||||
'js' => 'Javascript',
|
||||
'json' => 'JSON',
|
||||
'mysql' => 'MySQL',
|
||||
'objc' => 'Objective-C',
|
||||
'perl' => 'Perl',
|
||||
'php' => 'PHP',
|
||||
'puppet' => 'Puppet',
|
||||
'rest' => 'reStructuredText',
|
||||
'text' => 'Plain Text',
|
||||
'python' => 'Python',
|
||||
|
@ -1014,6 +1019,7 @@ return array(
|
|||
'remarkup' => 'Remarkup',
|
||||
'ruby' => 'Ruby',
|
||||
'xml' => 'XML',
|
||||
'yaml' => 'YAML',
|
||||
),
|
||||
|
||||
// This is an override list of regular expressions which allows you to choose
|
||||
|
@ -1035,6 +1041,7 @@ return array(
|
|||
// '@\\.([^.]+)\\.bak$@' => 1,
|
||||
|
||||
'@\.arcconfig$@' => 'js',
|
||||
'@\.arclint$@' => 'js',
|
||||
'@\.divinerconfig$@' => 'js',
|
||||
),
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
return array(
|
||||
'names' =>
|
||||
array(
|
||||
'core.pkg.css' => 'ac63f8ac',
|
||||
'core.pkg.css' => 'c94a698c',
|
||||
'core.pkg.js' => '7db41c19',
|
||||
'darkconsole.pkg.js' => 'ca8671ce',
|
||||
'differential.pkg.css' => 'fbf57382',
|
||||
|
@ -64,7 +64,6 @@ return array(
|
|||
'rsrc/css/application/diffusion/commit-view.css' => '92d1e8f9',
|
||||
'rsrc/css/application/diffusion/diffusion-icons.css' => '384a0f7d',
|
||||
'rsrc/css/application/diffusion/diffusion-source.css' => '66fdf661',
|
||||
'rsrc/css/application/directory/phabricator-jump-nav.css' => 'f0c5e726',
|
||||
'rsrc/css/application/feed/feed.css' => 'dd43ce00',
|
||||
'rsrc/css/application/files/global-drag-and-drop.css' => '697324ad',
|
||||
'rsrc/css/application/flag/flag.css' => '5337623f',
|
||||
|
@ -137,7 +136,7 @@ return array(
|
|||
'rsrc/css/phui/phui-info-panel.css' => '27ea50a1',
|
||||
'rsrc/css/phui/phui-list.css' => '43ed2d93',
|
||||
'rsrc/css/phui/phui-object-box.css' => 'ce92d8ec',
|
||||
'rsrc/css/phui/phui-object-item-list-view.css' => '16003f41',
|
||||
'rsrc/css/phui/phui-object-item-list-view.css' => '15c582b1',
|
||||
'rsrc/css/phui/phui-pinboard-view.css' => '874c22f9',
|
||||
'rsrc/css/phui/phui-property-list-view.css' => '2f7199e8',
|
||||
'rsrc/css/phui/phui-remarkup-preview.css' => '19ad512b',
|
||||
|
@ -483,7 +482,7 @@ return array(
|
|||
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
|
||||
'rsrc/js/phuix/PHUIXActionView.js' => '6e8cefa4',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca',
|
||||
'rsrc/swf/aphlict.swf' => 'abac967d',
|
||||
'rsrc/swf/aphlict.swf' => 'f22c1e40',
|
||||
),
|
||||
'symbols' =>
|
||||
array(
|
||||
|
@ -707,7 +706,6 @@ return array(
|
|||
'phabricator-flag-css' => '5337623f',
|
||||
'phabricator-hovercard' => '4f344388',
|
||||
'phabricator-hovercard-view-css' => '46a13cf0',
|
||||
'phabricator-jump-nav' => 'f0c5e726',
|
||||
'phabricator-keyboard-shortcut' => '1ae869f2',
|
||||
'phabricator-keyboard-shortcut-manager' => 'ad7a69ca',
|
||||
'phabricator-main-menu-view' => '72d1d2ef',
|
||||
|
@ -768,7 +766,7 @@ return array(
|
|||
'phui-info-panel-css' => '27ea50a1',
|
||||
'phui-list-view-css' => '43ed2d93',
|
||||
'phui-object-box-css' => 'ce92d8ec',
|
||||
'phui-object-item-list-view-css' => '16003f41',
|
||||
'phui-object-item-list-view-css' => '15c582b1',
|
||||
'phui-pinboard-view-css' => '874c22f9',
|
||||
'phui-property-list-view-css' => '2f7199e8',
|
||||
'phui-remarkup-preview-css' => '19ad512b',
|
||||
|
@ -2113,47 +2111,46 @@ return array(
|
|||
8 => 'aphront-tokenizer-control-css',
|
||||
9 => 'aphront-typeahead-control-css',
|
||||
10 => 'aphront-list-filter-view-css',
|
||||
11 => 'phabricator-jump-nav',
|
||||
12 => 'phabricator-remarkup-css',
|
||||
13 => 'syntax-highlighting-css',
|
||||
14 => 'aphront-pager-view-css',
|
||||
15 => 'phabricator-transaction-view-css',
|
||||
16 => 'aphront-tooltip-css',
|
||||
17 => 'phabricator-flag-css',
|
||||
18 => 'aphront-error-view-css',
|
||||
19 => 'sprite-remarkup-css',
|
||||
20 => 'sprite-gradient-css',
|
||||
21 => 'sprite-menu-css',
|
||||
22 => 'sprite-apps-css',
|
||||
23 => 'sprite-apps-large-css',
|
||||
24 => 'phabricator-main-menu-view',
|
||||
25 => 'phabricator-notification-css',
|
||||
26 => 'phabricator-notification-menu-css',
|
||||
27 => 'lightbox-attachment-css',
|
||||
28 => 'phui-header-view-css',
|
||||
29 => 'phabricator-filetree-view-css',
|
||||
30 => 'phabricator-nav-view-css',
|
||||
31 => 'phabricator-side-menu-view-css',
|
||||
32 => 'phabricator-crumbs-view-css',
|
||||
33 => 'phui-object-item-list-view-css',
|
||||
34 => 'global-drag-and-drop-css',
|
||||
35 => 'phui-spacing-css',
|
||||
36 => 'phui-form-css',
|
||||
37 => 'phui-icon-view-css',
|
||||
38 => 'phabricator-application-launch-view-css',
|
||||
39 => 'phabricator-action-list-view-css',
|
||||
40 => 'phui-property-list-view-css',
|
||||
41 => 'phui-tag-view-css',
|
||||
42 => 'phui-list-view-css',
|
||||
43 => 'font-fontawesome',
|
||||
44 => 'phui-font-icon-base-css',
|
||||
45 => 'sprite-main-header-css',
|
||||
46 => 'phui-box-css',
|
||||
47 => 'phui-object-box-css',
|
||||
48 => 'phui-timeline-view-css',
|
||||
49 => 'sprite-tokens-css',
|
||||
50 => 'tokens-css',
|
||||
51 => 'phui-status-list-view-css',
|
||||
11 => 'phabricator-remarkup-css',
|
||||
12 => 'syntax-highlighting-css',
|
||||
13 => 'aphront-pager-view-css',
|
||||
14 => 'phabricator-transaction-view-css',
|
||||
15 => 'aphront-tooltip-css',
|
||||
16 => 'phabricator-flag-css',
|
||||
17 => 'aphront-error-view-css',
|
||||
18 => 'sprite-remarkup-css',
|
||||
19 => 'sprite-gradient-css',
|
||||
20 => 'sprite-menu-css',
|
||||
21 => 'sprite-apps-css',
|
||||
22 => 'sprite-apps-large-css',
|
||||
23 => 'phabricator-main-menu-view',
|
||||
24 => 'phabricator-notification-css',
|
||||
25 => 'phabricator-notification-menu-css',
|
||||
26 => 'lightbox-attachment-css',
|
||||
27 => 'phui-header-view-css',
|
||||
28 => 'phabricator-filetree-view-css',
|
||||
29 => 'phabricator-nav-view-css',
|
||||
30 => 'phabricator-side-menu-view-css',
|
||||
31 => 'phabricator-crumbs-view-css',
|
||||
32 => 'phui-object-item-list-view-css',
|
||||
33 => 'global-drag-and-drop-css',
|
||||
34 => 'phui-spacing-css',
|
||||
35 => 'phui-form-css',
|
||||
36 => 'phui-icon-view-css',
|
||||
37 => 'phabricator-application-launch-view-css',
|
||||
38 => 'phabricator-action-list-view-css',
|
||||
39 => 'phui-property-list-view-css',
|
||||
40 => 'phui-tag-view-css',
|
||||
41 => 'phui-list-view-css',
|
||||
42 => 'font-fontawesome',
|
||||
43 => 'phui-font-icon-base-css',
|
||||
44 => 'sprite-main-header-css',
|
||||
45 => 'phui-box-css',
|
||||
46 => 'phui-object-box-css',
|
||||
47 => 'phui-timeline-view-css',
|
||||
48 => 'sprite-tokens-css',
|
||||
49 => 'tokens-css',
|
||||
50 => 'phui-status-list-view-css',
|
||||
),
|
||||
'core.pkg.js' =>
|
||||
array(
|
||||
|
|
|
@ -83,8 +83,6 @@ return array(
|
|||
'aphront-typeahead-control-css',
|
||||
'aphront-list-filter-view-css',
|
||||
|
||||
'phabricator-jump-nav',
|
||||
|
||||
'phabricator-remarkup-css',
|
||||
'syntax-highlighting-css',
|
||||
'aphront-pager-view-css',
|
||||
|
|
|
@ -32,7 +32,7 @@ foreach (new LiskMigrationIterator($table) as $revision) {
|
|||
if (phid_get_type($dst) == PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
|
||||
// At least one old install ran into some issues here. Skip the row if we
|
||||
// can't figure out what the destination PHID is. See here:
|
||||
// https://github.com/facebook/phabricator/pull/507
|
||||
// https://github.com/phacility/phabricator/pull/507
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,21 +119,21 @@ confirm
|
|||
|
||||
if [[ ! -e libphutil ]]
|
||||
then
|
||||
git clone git://github.com/facebook/libphutil.git
|
||||
git clone git://github.com/phacility/libphutil.git
|
||||
else
|
||||
(cd libphutil && git pull --rebase)
|
||||
fi
|
||||
|
||||
if [[ ! -e arcanist ]]
|
||||
then
|
||||
git clone git://github.com/facebook/arcanist.git
|
||||
git clone git://github.com/phacility/arcanist.git
|
||||
else
|
||||
(cd arcanist && git pull --rebase)
|
||||
fi
|
||||
|
||||
if [[ ! -e phabricator ]]
|
||||
then
|
||||
git clone git://github.com/facebook/phabricator.git
|
||||
git clone git://github.com/phacility/phabricator.git
|
||||
else
|
||||
(cd phabricator && git pull --rebase)
|
||||
fi
|
||||
|
|
|
@ -64,21 +64,21 @@ fi
|
|||
|
||||
if [ ! -e libphutil ]
|
||||
then
|
||||
git clone git://github.com/facebook/libphutil.git
|
||||
git clone git://github.com/phacility/libphutil.git
|
||||
else
|
||||
(cd libphutil && git pull --rebase)
|
||||
fi
|
||||
|
||||
if [ ! -e arcanist ]
|
||||
then
|
||||
git clone git://github.com/facebook/arcanist.git
|
||||
git clone git://github.com/phacility/arcanist.git
|
||||
else
|
||||
(cd arcanist && git pull --rebase)
|
||||
fi
|
||||
|
||||
if [ ! -e phabricator ]
|
||||
then
|
||||
git clone git://github.com/facebook/phabricator.git
|
||||
git clone git://github.com/phacility/phabricator.git
|
||||
else
|
||||
(cd phabricator && git pull --rebase)
|
||||
fi
|
||||
|
|
|
@ -99,58 +99,3 @@ final class DarkConsoleErrorLogPlugin extends DarkConsolePlugin {
|
|||
));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
$data = $this->getData();
|
||||
if (!$data) {
|
||||
return
|
||||
<x:frag>
|
||||
<div class="mu">No errors.</div>
|
||||
</x:frag>;
|
||||
}
|
||||
|
||||
$markup = <table class="LConsoleErrors" />;
|
||||
$alt = false;
|
||||
foreach ($data as $error) {
|
||||
$row = <tr class={$alt ? 'alt' : null} />;
|
||||
|
||||
$text = $error['error'];
|
||||
$text = preg_replace('/\(in .* on line \d+\)$/', '', trim($text));
|
||||
|
||||
$trace = $error['trace'];
|
||||
$trace = explode("\n", $trace);
|
||||
if (!$trace) {
|
||||
$trace = array('unknown@0@unknown');
|
||||
}
|
||||
|
||||
foreach ($trace as $idx => $traceline) {
|
||||
list($file, $line, $where) = array_merge(
|
||||
explode('@', $traceline),
|
||||
array('?', '?', '?'));
|
||||
if ($where == 'DarkConsole->addError' ||
|
||||
$where == 'debug_rlog') {
|
||||
unset($trace[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
$row->appendChild(<th rowspan={count($trace)}>{$text}</th>);
|
||||
|
||||
foreach ($trace as $traceline) {
|
||||
list($file, $line, $where) = array_merge(
|
||||
explode('@', $traceline),
|
||||
array('?', '?', '?'));
|
||||
$row->appendChild(<td>{$file}:{$line}</td>);
|
||||
$row->appendChild(<td>{$where}()</td>);
|
||||
$markup->appendChild($row);
|
||||
$row = <tr class={$alt ? 'alt' : null} />;
|
||||
}
|
||||
|
||||
$alt = !$alt;
|
||||
}
|
||||
|
||||
return
|
||||
<x:frag>
|
||||
<h1>Errors</h1>
|
||||
<div class="LConsoleErrors">{$markup}</div>
|
||||
</x:frag>;
|
||||
*/
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
final class PhabricatorApplicationAudit extends PhabricatorApplication {
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Audit Code');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
return '/audit/';
|
||||
}
|
||||
|
@ -14,6 +10,10 @@ final class PhabricatorApplicationAudit extends PhabricatorApplication {
|
|||
return 'audit';
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Browse and Audit Commits');
|
||||
}
|
||||
|
||||
public function getHelpURI() {
|
||||
return PhabricatorEnv::getDoclink('Audit User Guide');
|
||||
}
|
||||
|
|
|
@ -14,6 +14,10 @@ final class PhabricatorApplicationAuth extends PhabricatorApplication {
|
|||
return 'authentication';
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Configure Login and Registration');
|
||||
}
|
||||
|
||||
public function getHelpURI() {
|
||||
// NOTE: Although reasonable help exists for this in "Configuring Accounts
|
||||
// and Registration", specifying a help URI here means we get the menu
|
||||
|
|
|
@ -155,12 +155,10 @@ abstract class PhabricatorApplication
|
|||
}
|
||||
|
||||
public function getHelpURI() {
|
||||
// TODO: When these applications get created, link to their docs:
|
||||
//
|
||||
// - Drydock
|
||||
// - OAuth Server
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getOverview() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
final class PhabricatorApplicationCalendar extends PhabricatorApplication {
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Dates and Stuff');
|
||||
return pht('Upcoming Events');
|
||||
}
|
||||
|
||||
public function getFlavorText() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationChatLog extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Chat Log');
|
||||
return pht('IRC Logs');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -19,7 +19,7 @@ final class PhabricatorApplicationConduit extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return 'Conduit API Console';
|
||||
return pht('Phabricator Developer API Console');
|
||||
}
|
||||
|
||||
public function getTitleGlyph() {
|
||||
|
|
|
@ -22,6 +22,10 @@ final class PhabricatorApplicationConfig extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Configure Phabricator');
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/config/' => array(
|
||||
|
|
|
@ -42,6 +42,7 @@ final class PhabricatorSyntaxHighlightingConfigOptions
|
|||
'bash' => 'Bash Scripting',
|
||||
'brainfuck' => 'Brainf*ck',
|
||||
'c' => 'C',
|
||||
'coffee-script' => 'CoffeeScript',
|
||||
'cpp' => 'C++',
|
||||
'css' => 'CSS',
|
||||
'd' => 'D',
|
||||
|
@ -49,15 +50,19 @@ final class PhabricatorSyntaxHighlightingConfigOptions
|
|||
'django' => 'Django Templating',
|
||||
'erb' => 'Embedded Ruby/ERB',
|
||||
'erlang' => 'Erlang',
|
||||
'go' => 'Golang',
|
||||
'groovy' => 'Groovy',
|
||||
'haskell' => 'Haskell',
|
||||
'html' => 'HTML',
|
||||
'invisible' => 'Invisible',
|
||||
'java' => 'Java',
|
||||
'js' => 'Javascript',
|
||||
'json' => 'JSON',
|
||||
'mysql' => 'MySQL',
|
||||
'objc' => 'Objective-C',
|
||||
'perl' => 'Perl',
|
||||
'php' => 'PHP',
|
||||
'puppet' => 'Puppet',
|
||||
'rest' => 'reStructuredText',
|
||||
'text' => 'Plain Text',
|
||||
'python' => 'Python',
|
||||
|
@ -65,6 +70,7 @@ final class PhabricatorSyntaxHighlightingConfigOptions
|
|||
'remarkup' => 'Remarkup',
|
||||
'ruby' => 'Ruby',
|
||||
'xml' => 'XML',
|
||||
'yaml' => 'YAML',
|
||||
))
|
||||
->setSummary(
|
||||
pht("Set the language list which appears in dropdowns."))
|
||||
|
@ -77,6 +83,7 @@ final class PhabricatorSyntaxHighlightingConfigOptions
|
|||
'wild',
|
||||
array(
|
||||
'@\.arcconfig$@' => 'js',
|
||||
'@\.arclint$@' => 'js',
|
||||
'@\.divinerconfig$@' => 'js',
|
||||
))
|
||||
->setSummary(
|
||||
|
|
|
@ -10,7 +10,7 @@ final class PhabricatorApplicationConpherence extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Messaging');
|
||||
return pht('Send Messages');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -11,7 +11,7 @@ final class PhabricatorApplicationCountdown extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Countdown Timers');
|
||||
return pht('Countdown to Events');
|
||||
}
|
||||
|
||||
public function getTitleGlyph() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationDaemons extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Manage Daemons');
|
||||
return pht('Manage Phabricator Daemons');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationDashboard extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Such Data');
|
||||
return pht('Create Custom Pages');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -26,10 +26,14 @@ final class PhabricatorDashboardViewController
|
|||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Dashboard %d', $dashboard->getID()));
|
||||
|
||||
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->renderDashboard();
|
||||
if ($dashboard->getPanelPHIDs()) {
|
||||
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->renderDashboard();
|
||||
} else {
|
||||
$rendered_dashboard = $this->buildEmptyView();
|
||||
}
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
|
@ -50,9 +54,24 @@ final class PhabricatorDashboardViewController
|
|||
id(new PHUIListItemView())
|
||||
->setIcon('fa-th')
|
||||
->setName(pht('Manage Dashboard'))
|
||||
->setHref($this->getApplicationURI()."manage/{$id}/"));
|
||||
->setHref($this->getApplicationURI("manage/{$id}/")));
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
public function buildEmptyView() {
|
||||
$id = $this->id;
|
||||
$manage_uri = $this->getApplicationURI("manage/{$id}/");
|
||||
|
||||
return id(new AphrontErrorView())
|
||||
->setSeverity(AphrontErrorView::SEVERITY_NODATA)
|
||||
->appendChild(
|
||||
pht('This dashboard has no panels '.
|
||||
'yet. Use %s to add panels.',
|
||||
phutil_tag(
|
||||
'a',
|
||||
array('href'=>$manage_uri),
|
||||
pht('Manage Dashboard'))));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,14 @@ final class PhabricatorApplicationDifferential extends PhabricatorApplication {
|
|||
);
|
||||
}
|
||||
|
||||
public function getOverview() {
|
||||
return pht(<<<EOTEXT
|
||||
Differential is a **code review application** which allows engineers to review,
|
||||
discuss and approve changes to software.
|
||||
EOTEXT
|
||||
);
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/D(?P<id>[1-9]\d*)' => 'DifferentialRevisionViewController',
|
||||
|
|
|
@ -44,7 +44,7 @@ final class DifferentialTestPlanField
|
|||
protected function getCoreFieldRequiredErrorString() {
|
||||
return pht(
|
||||
'You must provide a test plan. Describe the actions you performed '.
|
||||
'to verify the behvaior of this change.');
|
||||
'to verify the behavior of this change.');
|
||||
}
|
||||
|
||||
public function readValueFromRequest(AphrontRequest $request) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
final class PhabricatorApplicationDiffusion extends PhabricatorApplication {
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Repository Browser');
|
||||
return pht('Host and Browse Repositories');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
|
|
|
@ -9,6 +9,7 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
|||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$drequest = $this->getDiffusionRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$before = $request->getStr('before');
|
||||
if ($before) {
|
||||
|
@ -17,7 +18,7 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
|||
|
||||
$path = $drequest->getPath();
|
||||
|
||||
$preferences = $request->getUser()->loadPreferences();
|
||||
$preferences = $viewer->loadPreferences();
|
||||
|
||||
$show_blame = $request->getBool(
|
||||
'blame',
|
||||
|
@ -31,7 +32,7 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
|||
true));
|
||||
|
||||
$view = $request->getStr('view');
|
||||
if ($request->isFormPost() && $view != 'raw') {
|
||||
if ($request->isFormPost() && $view != 'raw' && $viewer->isLoggedIn()) {
|
||||
$preferences->setPreference(
|
||||
PhabricatorUserPreferences::PREFERENCE_DIFFUSION_BLAME,
|
||||
$show_blame);
|
||||
|
@ -354,7 +355,7 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
|||
->setHref($base_uri->alter('blame', $blame_value))
|
||||
->setIcon($blame_icon)
|
||||
->setUser($viewer)
|
||||
->setRenderAsForm(true));
|
||||
->setRenderAsForm($viewer->isLoggedIn()));
|
||||
|
||||
if ($show_color) {
|
||||
$highlight_text = pht('Disable Highlighting');
|
||||
|
@ -372,7 +373,7 @@ final class DiffusionBrowseFileController extends DiffusionBrowseController {
|
|||
->setHref($base_uri->alter('color', $highlight_value))
|
||||
->setIcon($highlight_icon)
|
||||
->setUser($viewer)
|
||||
->setRenderAsForm(true));
|
||||
->setRenderAsForm($viewer->isLoggedIn()));
|
||||
|
||||
$href = null;
|
||||
if ($this->getRequest()->getStr('lint') !== null) {
|
||||
|
|
|
@ -36,7 +36,7 @@ final class PhabricatorApplicationDiviner extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getApplicationGroup() {
|
||||
return self::GROUP_COMMUNICATION;
|
||||
return self::GROUP_UTILITIES;
|
||||
}
|
||||
|
||||
public function getRemarkupRules() {
|
||||
|
|
|
@ -6,14 +6,14 @@ final class PhabricatorApplicationDoorkeeper extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
return '/doorkeeper/';
|
||||
}
|
||||
|
||||
public function shouldAppearInLaunchView() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Connect to Other Software');
|
||||
}
|
||||
|
||||
public function getRemarkupRules() {
|
||||
return array(
|
||||
new DoorkeeperRemarkupRuleAsana(),
|
||||
|
|
|
@ -30,6 +30,10 @@ final class PhabricatorApplicationDrydock extends PhabricatorApplication {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getHelpURI() {
|
||||
return PhabricatorEnv::getDoclink('Drydock User Guide');
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/drydock/' => array(
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
final class PhabricatorApplicationFact extends PhabricatorApplication {
|
||||
|
||||
public function getShortDescription() {
|
||||
return 'Analyze Data';
|
||||
return pht('Chart and Analyze Data');
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationFeed extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Review Activity');
|
||||
return pht('Review Recent Activity');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
final class PhabricatorApplicationFlags extends PhabricatorApplication {
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Reminders');
|
||||
return pht('Personal Bookmarks and Reminders');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
|
@ -25,7 +25,7 @@ final class PhabricatorApplicationFlags extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getApplicationGroup() {
|
||||
return self::GROUP_ORGANIZATION;
|
||||
return self::GROUP_UTILITIES;
|
||||
}
|
||||
|
||||
public function loadStatus(PhabricatorUser $user) {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationHarbormaster extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Continuous Build');
|
||||
return pht('Builds and Continuous Integration');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -16,10 +16,6 @@ final class PhabricatorHomeMainController
|
|||
|
||||
public function processRequest() {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
if ($this->filter == 'jump') {
|
||||
return $this->buildJumpResponse();
|
||||
}
|
||||
$nav = $this->buildNav();
|
||||
|
||||
$dashboard = PhabricatorDashboardInstall::getDashboard(
|
||||
|
@ -92,8 +88,6 @@ final class PhabricatorHomeMainController
|
|||
$welcome_panel = null;
|
||||
}
|
||||
|
||||
$jump_panel = $this->buildJumpPanel();
|
||||
|
||||
if ($has_differential) {
|
||||
$revision_panel = $this->buildRevisionPanel();
|
||||
} else {
|
||||
|
@ -101,7 +95,6 @@ final class PhabricatorHomeMainController
|
|||
}
|
||||
|
||||
$content = array(
|
||||
$jump_panel,
|
||||
$welcome_panel,
|
||||
$unbreak_panel,
|
||||
$triage_panel,
|
||||
|
@ -118,27 +111,6 @@ final class PhabricatorHomeMainController
|
|||
|
||||
}
|
||||
|
||||
private function buildJumpResponse() {
|
||||
$request = $this->getRequest();
|
||||
$jump = $request->getStr('jump');
|
||||
|
||||
$response = PhabricatorJumpNavHandler::getJumpResponse(
|
||||
$request->getUser(),
|
||||
$jump);
|
||||
|
||||
if ($response) {
|
||||
return $response;
|
||||
} else if ($request->isFormPost()) {
|
||||
$uri = new PhutilURI('/search/');
|
||||
$uri->setQueryParam('query', $jump);
|
||||
$uri->setQueryParam('search:primary', 'true');
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI((string)$uri);
|
||||
} else {
|
||||
return id(new AphrontRedirectResponse())->setURI('/');
|
||||
}
|
||||
}
|
||||
|
||||
private function buildUnbreakNowPanel() {
|
||||
$unbreak_now = PhabricatorEnv::getEnvConfig(
|
||||
'maniphest.priorities.unbreak-now');
|
||||
|
@ -330,73 +302,6 @@ final class PhabricatorHomeMainController
|
|||
return $view;
|
||||
}
|
||||
|
||||
private function buildJumpPanel($query=null) {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$uniq_id = celerity_generate_unique_node_id();
|
||||
|
||||
Javelin::initBehavior(
|
||||
'phabricator-autofocus',
|
||||
array(
|
||||
'id' => $uniq_id,
|
||||
));
|
||||
|
||||
require_celerity_resource('phabricator-jump-nav');
|
||||
|
||||
$doc_href = PhabricatorEnv::getDocLink('Jump Nav User Guide');
|
||||
$doc_link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $doc_href,
|
||||
),
|
||||
'Jump Nav User Guide');
|
||||
|
||||
$jump_input = phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'text',
|
||||
'class' => 'phabricator-jump-nav',
|
||||
'name' => 'jump',
|
||||
'id' => $uniq_id,
|
||||
'value' => $query,
|
||||
));
|
||||
$jump_caption = phutil_tag(
|
||||
'p',
|
||||
array(
|
||||
'class' => 'phabricator-jump-nav-caption',
|
||||
),
|
||||
hsprintf(
|
||||
'Enter the name of an object like <tt>D123</tt> to quickly jump to '.
|
||||
'it. See %s or type <tt>help</tt>.',
|
||||
$doc_link));
|
||||
|
||||
$form = phabricator_form(
|
||||
$user,
|
||||
array(
|
||||
'action' => '/jump/',
|
||||
'method' => 'POST',
|
||||
'class' => 'phabricator-jump-nav-form',
|
||||
),
|
||||
array(
|
||||
$jump_input,
|
||||
$jump_caption,
|
||||
));
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->setNoBackground();
|
||||
// $panel->appendChild();
|
||||
|
||||
$list_filter = new AphrontListFilterView();
|
||||
$list_filter->appendChild($form);
|
||||
|
||||
$container = phutil_tag('div',
|
||||
array('class' => 'phabricator-jump-nav-container'),
|
||||
$list_filter);
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
private function renderSectionHeader($title, $href) {
|
||||
$header = phutil_tag(
|
||||
'a',
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationLegalpad extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Legal Documents');
|
||||
return pht('Agreements and Signatures');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -218,9 +218,9 @@ EOTEXT
|
|||
->setSummary(pht("Custom Maniphest fields."))
|
||||
->setDescription(
|
||||
pht(
|
||||
"Array of custom fields for Maniphest tasks. For details on ".
|
||||
"adding custom fields to Maniphest, see 'Maniphest User Guide: ".
|
||||
"Adding Custom Fields'."))
|
||||
'Array of custom fields for Maniphest tasks. For details on '.
|
||||
'adding custom fields to Maniphest, see "Configuring Custom '.
|
||||
'Fields" in the documentation.'))
|
||||
->addExample(
|
||||
'{"mycompany:estimated-hours": {"name": "Estimated Hours", '.
|
||||
'"type": "int", "caption": "Estimated number of hours this will '.
|
||||
|
|
|
@ -11,7 +11,7 @@ final class PhabricatorApplicationApplications extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return 'Installed Applications';
|
||||
return pht('Explore More Applications');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
@ -26,7 +26,7 @@ final class PhabricatorApplicationApplications extends PhabricatorApplication {
|
|||
return self::GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/applications/' => array(
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' =>
|
||||
|
@ -38,7 +38,6 @@ final class PhabricatorApplicationApplications extends PhabricatorApplication {
|
|||
'(?P<application>\w+)/(?P<action>install|uninstall)/' =>
|
||||
'PhabricatorApplicationUninstallController',
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorApplicationDetailViewController
|
||||
extends PhabricatorApplicationsController{
|
||||
extends PhabricatorApplicationsController {
|
||||
|
||||
private $application;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->application = $data['application'];
|
||||
}
|
||||
|
@ -61,16 +65,37 @@ final class PhabricatorApplicationDetailViewController
|
|||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$properties = id(new PHUIPropertyListView())
|
||||
->addProperty(pht('Description'), $application->getShortDescription());
|
||||
$properties = id(new PHUIPropertyListView());
|
||||
$properties->setActionList($actions);
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Description'),
|
||||
$application->getShortDescription());
|
||||
|
||||
if ($application->getFlavorText()) {
|
||||
$properties->addProperty(
|
||||
null,
|
||||
phutil_tag('em', array(), $application->getFlavorText()));
|
||||
}
|
||||
|
||||
if ($application->isBeta()) {
|
||||
$properties->addProperty(
|
||||
pht('Release'),
|
||||
pht('Beta'));
|
||||
}
|
||||
|
||||
$overview = $application->getOverview();
|
||||
if ($overview) {
|
||||
$properties->addSectionHeader(
|
||||
pht('Overview'),
|
||||
PHUIPropertyListView::ICON_SUMMARY);
|
||||
$properties->addTextContent(
|
||||
PhabricatorMarkupEngine::renderOneObject(
|
||||
id(new PhabricatorMarkupOneOff())->setContent($overview),
|
||||
'default',
|
||||
$viewer));
|
||||
}
|
||||
|
||||
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
|
||||
$viewer,
|
||||
$application);
|
||||
|
@ -94,6 +119,14 @@ final class PhabricatorApplicationDetailViewController
|
|||
->setUser($user)
|
||||
->setObjectURI($this->getRequest()->getRequestURI());
|
||||
|
||||
if ($selected->getHelpURI()) {
|
||||
$view->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Help / Documentation'))
|
||||
->setIcon('fa-life-ring')
|
||||
->setHref($selected->getHelpURI()));
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$user,
|
||||
$selected,
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorApplicationEditController
|
||||
extends PhabricatorApplicationsController{
|
||||
extends PhabricatorApplicationsController {
|
||||
|
||||
private $application;
|
||||
|
||||
public function shouldRequireAdmin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->application = $data['application'];
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ final class PhabricatorApplicationUninstallController
|
|||
private $application;
|
||||
private $action;
|
||||
|
||||
public function shouldRequireAdmin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->application = $data['application'];
|
||||
$this->action = $data['action'];
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
abstract class PhabricatorApplicationsController extends PhabricatorController {
|
||||
|
||||
public function shouldRequireAdmin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function buildSideNavView($for_app = false) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@ final class PhabricatorApplicationsListController
|
|||
|
||||
private $queryKey;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->queryKey = idx($data, 'queryKey');
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@ final class PhabricatorAppSearchEngine
|
|||
$saved->setParameter(
|
||||
'firstParty',
|
||||
$this->readBoolFromRequest($request, 'firstParty'));
|
||||
$saved->setParameter(
|
||||
'launchable',
|
||||
$this->readBoolFromRequest($request, 'launchable'));
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
@ -54,6 +57,11 @@ final class PhabricatorAppSearchEngine
|
|||
$query->withFirstParty($first_party);
|
||||
}
|
||||
|
||||
$launchable = $saved->getParameter('launchable');
|
||||
if ($launchable !== null) {
|
||||
$query->withLaunchable($launchable);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
@ -99,6 +107,17 @@ final class PhabricatorAppSearchEngine
|
|||
'' => pht('Show All Applications'),
|
||||
'true' => pht('Show First-Party Applications'),
|
||||
'false' => pht('Show Third-Party Applications'),
|
||||
)))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Launchable'))
|
||||
->setName('launchable')
|
||||
->setValue($this->getBoolFromQuery($saved, 'launchable'))
|
||||
->setOptions(
|
||||
array(
|
||||
'' => pht('Show All Applications'),
|
||||
'true' => pht('Show Launchable Applications'),
|
||||
'false' => pht('Show Non-Launchable Applications'),
|
||||
)));
|
||||
|
||||
}
|
||||
|
@ -109,6 +128,7 @@ final class PhabricatorAppSearchEngine
|
|||
|
||||
public function getBuiltinQueryNames() {
|
||||
$names = array(
|
||||
'launcher' => pht('Launcher'),
|
||||
'all' => pht('All Applications'),
|
||||
);
|
||||
|
||||
|
@ -121,6 +141,10 @@ final class PhabricatorAppSearchEngine
|
|||
$query->setQueryKey($query_key);
|
||||
|
||||
switch ($query_key) {
|
||||
case 'launcher':
|
||||
return $query
|
||||
->setParameter('installed', true)
|
||||
->setParameter('launchable', true);
|
||||
case 'all':
|
||||
return $query;
|
||||
}
|
||||
|
@ -129,33 +153,93 @@ final class PhabricatorAppSearchEngine
|
|||
}
|
||||
|
||||
protected function renderResultList(
|
||||
array $applications,
|
||||
array $all_applications,
|
||||
PhabricatorSavedQuery $query,
|
||||
array $handle) {
|
||||
assert_instances_of($applications, 'PhabricatorApplication');
|
||||
assert_instances_of($all_applications, 'PhabricatorApplication');
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
$all_applications = msort($all_applications, 'getName');
|
||||
|
||||
$applications = msort($applications, 'getName');
|
||||
|
||||
foreach ($applications as $application) {
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setHeader($application->getName())
|
||||
->setHref('/applications/view/'.get_class($application).'/')
|
||||
->addAttribute($application->getShortDescription());
|
||||
|
||||
if (!$application->isInstalled()) {
|
||||
$item->addIcon('delete', pht('Uninstalled'));
|
||||
}
|
||||
|
||||
if ($application->isBeta()) {
|
||||
$item->addIcon('lint-warning', pht('Beta'));
|
||||
}
|
||||
|
||||
$list->addItem($item);
|
||||
if ($query->getQueryKey() == 'launcher') {
|
||||
$groups = mgroup($all_applications, 'getApplicationGroup');
|
||||
} else {
|
||||
$groups = array($all_applications);
|
||||
}
|
||||
|
||||
return $list;
|
||||
$group_names = PhabricatorApplication::getApplicationGroups();
|
||||
$groups = array_select_keys($groups, array_keys($group_names)) + $groups;
|
||||
|
||||
$results = array();
|
||||
foreach ($groups as $group => $applications) {
|
||||
if (count($groups) > 1) {
|
||||
$results[] = phutil_tag(
|
||||
'h1',
|
||||
array(
|
||||
'class' => 'launcher-header',
|
||||
),
|
||||
idx($group_names, $group, $group));
|
||||
}
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
$list->addClass('phui-object-item-launcher-list');
|
||||
|
||||
foreach ($applications as $application) {
|
||||
$icon = $application->getIconName();
|
||||
if (!$icon) {
|
||||
$icon = 'application';
|
||||
}
|
||||
|
||||
// TODO: This sheet doesn't work the same way other sheets do so it
|
||||
// ends up with the wrong classes if we try to use PHUIIconView. This
|
||||
// is probably all changing in the redesign anyway.
|
||||
|
||||
$icon_view = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phui-icon-view '.
|
||||
'sprite-apps-large apps-'.$icon.'-dark-large',
|
||||
'aural' => false,
|
||||
),
|
||||
'');
|
||||
|
||||
$description = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'style' => 'white-space: nowrap; '.
|
||||
'overflow: hidden; '.
|
||||
'text-overflow: ellipsis;',
|
||||
),
|
||||
$application->getShortDescription());
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setHeader($application->getName())
|
||||
->setImageIcon($icon_view)
|
||||
->addAttribute($description)
|
||||
->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setName(pht('Help/Options'))
|
||||
->setIcon('fa-cog')
|
||||
->setHref('/applications/view/'.get_class($application).'/'));
|
||||
|
||||
if ($application->getBaseURI()) {
|
||||
$item->setHref($application->getBaseURI());
|
||||
}
|
||||
|
||||
if (!$application->isInstalled()) {
|
||||
$item->addIcon('delete', pht('Uninstalled'));
|
||||
}
|
||||
|
||||
if ($application->isBeta()) {
|
||||
$item->addIcon('fa-star-half-o grey', pht('Beta'));
|
||||
}
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
$results[] = $list;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ final class PhabricatorApplicationQuery
|
|||
private $nameContains;
|
||||
private $unlisted;
|
||||
private $classes;
|
||||
private $launchable;
|
||||
private $phids;
|
||||
|
||||
const ORDER_APPLICATION = 'order:application';
|
||||
|
@ -41,6 +42,11 @@ final class PhabricatorApplicationQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withLaunchable($launchable) {
|
||||
$this->launchable = $launchable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withClasses(array $classes) {
|
||||
$this->classes = $classes;
|
||||
return $this;
|
||||
|
@ -117,6 +123,15 @@ final class PhabricatorApplicationQuery
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->launchable !== null) {
|
||||
foreach ($apps as $key => $app) {
|
||||
if ($app->shouldAppearInLaunchView() != $this->launchable) {
|
||||
unset($apps[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch ($this->order) {
|
||||
case self::ORDER_NAME:
|
||||
$apps = msort($apps, 'getName');
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
final class PhabricatorApplicationMetaMTA extends PhabricatorApplication {
|
||||
|
||||
public function getBaseURI() {
|
||||
return '/mail/';
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
return 'metamta';
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Delivers Mail');
|
||||
}
|
||||
|
||||
public function getFlavorText() {
|
||||
return pht('Yo dawg, we heard you like MTAs.');
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationNotifications extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Beep Beep Bloop');
|
||||
return pht('Real-Time Updates and Alerts');
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
|
|
|
@ -27,6 +27,10 @@ final class PhabricatorApplicationNuance extends PhabricatorApplication {
|
|||
return '/nuance/';
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('High-Volume Task Queues');
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/nuance/' => array(
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationOAuthServer extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('OAuth Provider');
|
||||
return pht('OAuth Login Provider');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
@ -23,13 +23,17 @@ final class PhabricatorApplicationOAuthServer extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getApplicationGroup() {
|
||||
return self::GROUP_UTILITIES;
|
||||
return self::GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function isBeta() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHelpURI() {
|
||||
return PhabricatorEnv::getDoclink('Using the Phabricator OAuth Server');
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/oauthserver/' => array(
|
||||
|
|
|
@ -11,7 +11,7 @@ final class PhabricatorApplicationOwners extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Group Source Code');
|
||||
return pht('Track Ownership of Source Code');
|
||||
}
|
||||
|
||||
public function getTitleGlyph() {
|
||||
|
@ -27,7 +27,7 @@ final class PhabricatorApplicationOwners extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getApplicationGroup() {
|
||||
return self::GROUP_ORGANIZATION;
|
||||
return self::GROUP_UTILITIES;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationPassphrase extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Credential Management');
|
||||
return pht('Store Passwords and Credentials');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -26,23 +26,18 @@ final class PassphraseCredentialEditController extends PassphraseController {
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$type = PassphraseCredentialType::getTypeByConstant(
|
||||
$credential->getCredentialType());
|
||||
if (!$type) {
|
||||
throw new Exception(pht('Credential has invalid type "%s"!', $type));
|
||||
}
|
||||
|
||||
if (!$type->isCreateable()) {
|
||||
throw new Exception(
|
||||
pht('Credential has noncreateable type "%s"!', $type));
|
||||
}
|
||||
$type = $this->getCredentialType($credential->getCredentialType());
|
||||
|
||||
$is_new = false;
|
||||
} else {
|
||||
$type_const = $request->getStr('type');
|
||||
$type = PassphraseCredentialType::getTypeByConstant($type_const);
|
||||
if (!$type) {
|
||||
return new Aphront404Response();
|
||||
$type = $this->getCredentialType($type_const);
|
||||
|
||||
if (!$type->isCreateable()) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Credential has noncreateable type "%s"!',
|
||||
$credential->getCredentialType()));
|
||||
}
|
||||
|
||||
$credential = PassphraseCredential::initializeNewCredential($viewer)
|
||||
|
@ -358,4 +353,15 @@ final class PassphraseCredentialEditController extends PassphraseController {
|
|||
));
|
||||
}
|
||||
|
||||
private function getCredentialType($type_const) {
|
||||
$type = PassphraseCredentialType::getTypeByConstant($type_const);
|
||||
|
||||
if (!$type) {
|
||||
throw new Exception(
|
||||
pht('Credential has invalid type "%s"!', $type_const));
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ final class PhabricatorApplicationPaste extends PhabricatorApplication {
|
|||
return self::GROUP_UTILITIES;
|
||||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Share Text Snippets');
|
||||
}
|
||||
|
||||
public function getRemarkupRules() {
|
||||
return array(
|
||||
new PhabricatorPasteRemarkupRule(),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
final class PhabricatorApplicationPeople extends PhabricatorApplication {
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('User Accounts');
|
||||
return pht('User Accounts and Profiles');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationPhlux extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Configuration Store');
|
||||
return pht('Key/Value Configuration Store');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationPholio extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Design Review');
|
||||
return pht('Review Mocks and Design');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationPhortune extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Account and Billing');
|
||||
return pht('Accounts and Billing');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
final class PhabricatorApplicationPhrequent extends PhabricatorApplication {
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Track Time');
|
||||
return pht('Track Time Spent');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
|
@ -19,7 +19,7 @@ final class PhabricatorApplicationPhrequent extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getApplicationGroup() {
|
||||
return self::GROUP_ORGANIZATION;
|
||||
return self::GROUP_UTILITIES;
|
||||
}
|
||||
|
||||
public function getApplicationOrder() {
|
||||
|
|
|
@ -23,6 +23,11 @@ final class PhrequentTimeBlock extends Phobject {
|
|||
public function getObjectTimeRanges($now) {
|
||||
$ranges = array();
|
||||
|
||||
$range_start = time();
|
||||
foreach ($this->events as $event) {
|
||||
$range_start = min($range_start, $event->getDateStarted());
|
||||
}
|
||||
|
||||
$object_ranges = array();
|
||||
foreach ($this->events as $event) {
|
||||
|
||||
|
|
|
@ -14,10 +14,12 @@ final class PhabricatorPolicyDataTestCase extends PhabricatorTestCase {
|
|||
$proj_a = id(new PhabricatorProject())
|
||||
->setName('A')
|
||||
->setAuthorPHID($author->getPHID())
|
||||
->setIcon('fa-briefcase')
|
||||
->save();
|
||||
$proj_b = id(new PhabricatorProject())
|
||||
->setName('B')
|
||||
->setAuthorPHID($author->getPHID())
|
||||
->setIcon('fa-briefcase')
|
||||
->save();
|
||||
|
||||
$proj_a->setViewPolicy($proj_b->getPHID())->save();
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationPonder extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Find Answers');
|
||||
return pht('Questions and Answers');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationProject extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Organize Work');
|
||||
return pht('Create Groups, Tags, and Projects');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
|
|
|
@ -305,8 +305,15 @@ final class PhabricatorProjectTransactionEditor
|
|||
|
||||
$slug_xaction = last($xactions);
|
||||
$new = $slug_xaction->getNewValue();
|
||||
$slugs_used_already = id(new PhabricatorProjectSlug())
|
||||
->loadAllWhere('slug IN (%Ls)', $new);
|
||||
|
||||
if ($new) {
|
||||
$slugs_used_already = id(new PhabricatorProjectSlug())
|
||||
->loadAllWhere('slug IN (%Ls)', $new);
|
||||
} else {
|
||||
// The project doesn't have any extra slugs.
|
||||
$slugs_used_already = array();
|
||||
}
|
||||
|
||||
$slugs_used_already = mgroup($slugs_used_already, 'getProjectPHID');
|
||||
foreach ($slugs_used_already as $project_phid => $used_slugs) {
|
||||
$used_slug_strs = mpull($used_slugs, 'getSlug');
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationReleeph extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Release Branches');
|
||||
return pht('Pull Requests');
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
|
|
|
@ -14,7 +14,7 @@ final class PhabricatorApplicationRepositories extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return 'Track Repositories';
|
||||
return pht('(Deprecated)');
|
||||
}
|
||||
|
||||
public function getTitleGlyph() {
|
||||
|
|
|
@ -384,7 +384,7 @@ final class PhabricatorRepositoryPullEngine
|
|||
// This behavior has been reverted, but users who updated between Feb 1,
|
||||
// 2012 and Mar 1, 2012 will have the erroring version. Do a dumb test
|
||||
// against stdout to check for this possibility.
|
||||
// See: https://github.com/facebook/phabricator/issues/101/
|
||||
// See: https://github.com/phacility/phabricator/issues/101/
|
||||
|
||||
// NOTE: Mercurial has translated versions, which translate this error
|
||||
// string. In a translated version, the string will be something else,
|
||||
|
|
|
@ -58,6 +58,10 @@ final class PhabricatorRepositoryManagementParentsWorkflow
|
|||
|
||||
$graph = array();
|
||||
foreach ($refs as $ref) {
|
||||
if (!$repo->shouldTrackBranch($ref->getRefName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$console->writeOut(
|
||||
"%s\n",
|
||||
pht('Rebuilding branch "%s"...', $ref->getRefName()));
|
||||
|
|
|
@ -11,7 +11,7 @@ final class PhabricatorApplicationSearch extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Search & Find');
|
||||
return pht('Full-Text Search');
|
||||
}
|
||||
|
||||
public function getFlavorText() {
|
||||
|
|
|
@ -97,7 +97,7 @@ final class PhabricatorSearchEngineElastic extends PhabricatorSearchEngine {
|
|||
|
||||
if (strlen($query->getParameter('query'))) {
|
||||
$spec[] = array(
|
||||
'field' => array(
|
||||
'term' => array(
|
||||
'field.corpus' => $query->getParameter('query'),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationSettings extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return 'User Preferences';
|
||||
return pht('User Preferences');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
@ -18,6 +18,10 @@ final class PhabricatorApplicationSettings extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function shouldAppearInLaunchView() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/settings/' => array(
|
||||
|
|
|
@ -19,7 +19,7 @@ final class PhabricatorApplicationTokens extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return pht('Acquire Trinkets');
|
||||
return pht('Award and Acquire Trinkets');
|
||||
}
|
||||
|
||||
public function getApplicationGroup() {
|
||||
|
|
|
@ -7,7 +7,7 @@ final class PhabricatorApplicationUIExamples extends PhabricatorApplication {
|
|||
}
|
||||
|
||||
public function getShortDescription() {
|
||||
return 'Developer UI Examples';
|
||||
return pht('Phabricator Developer UI Examples');
|
||||
}
|
||||
|
||||
public function getIconName() {
|
||||
|
|
|
@ -39,7 +39,7 @@ requests, general questions, or random feedback this way, too.
|
|||
= GitHub Issues =
|
||||
|
||||
You can also use
|
||||
[[https://github.com/facebook/phabricator/issues/new | GitHub Issues]] if you
|
||||
[[https://github.com/phacility/phabricator/issues/new | GitHub Issues]] if you
|
||||
prefer.
|
||||
|
||||
= IRC =
|
||||
|
|
|
@ -95,9 +95,9 @@ Now that you have all that stuff installed, grab Phabricator and its
|
|||
dependencies:
|
||||
|
||||
$ cd somewhere/ # pick some install directory
|
||||
somewhere/ $ git clone git://github.com/facebook/libphutil.git
|
||||
somewhere/ $ git clone git://github.com/facebook/arcanist.git
|
||||
somewhere/ $ git clone git://github.com/facebook/phabricator.git
|
||||
somewhere/ $ git clone git://github.com/phacility/libphutil.git
|
||||
somewhere/ $ git clone git://github.com/phacility/arcanist.git
|
||||
somewhere/ $ git clone git://github.com/phacility/phabricator.git
|
||||
|
||||
= Installing APC (Optional) =
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ have PHP installed, you can download it from <http://www.php.net/>.
|
|||
|
||||
To install Arcanist, pick an install directory and clone the code from GitHub:
|
||||
|
||||
some_install_path/ $ git clone git://github.com/facebook/libphutil.git
|
||||
some_install_path/ $ git clone git://github.com/facebook/arcanist.git
|
||||
some_install_path/ $ git clone git://github.com/phacility/libphutil.git
|
||||
some_install_path/ $ git clone git://github.com/phacility/arcanist.git
|
||||
|
||||
This should leave you with a directory structure like this
|
||||
|
||||
|
@ -162,7 +162,7 @@ several sources:
|
|||
|
||||
The first place where the setting is defined wins.
|
||||
|
||||
Existing settings can be printed with `arc set-config --show`.
|
||||
Existing settings can be printed with `arc get-config`.
|
||||
|
||||
== Next Steps ==
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ These options are supported, but their use is discouraged:
|
|||
solution to certificate validity problems, and is discouraged. Instead,
|
||||
use valid certificates.
|
||||
|
||||
For a complete list of options, run `arc set-config --show`. Although all
|
||||
For a complete list of options, run `arc get-config`. Although all
|
||||
options can be set in `.arcconfig`, some options (like `editor`) usually do not
|
||||
make sense to set here because they're likely to vary from user to user.
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ Then install Arcanist itself:
|
|||
|
||||
$ mkdir somewhere/
|
||||
$ cd somewhere/
|
||||
somewhere/ $ git clone git://github.com/facebook/libphutil.git
|
||||
somewhere/ $ git clone git://github.com/facebook/arcanist.git
|
||||
somewhere/ $ git clone git://github.com/phacility/libphutil.git
|
||||
somewhere/ $ git clone git://github.com/phacility/arcanist.git
|
||||
|
||||
Add `arc` to your path:
|
||||
|
||||
|
|
|
@ -142,7 +142,6 @@ final class PHUIFeedStoryView extends AphrontView {
|
|||
|
||||
require_celerity_resource('phui-feed-story-css');
|
||||
Javelin::initBehavior('phabricator-hovercards');
|
||||
$oneline = !$this->hasChildren();
|
||||
|
||||
$body = null;
|
||||
$foot = null;
|
||||
|
@ -186,18 +185,6 @@ final class PHUIFeedStoryView extends AphrontView {
|
|||
$icon->setSpriteSheet(PHUIIconView::SPRITE_APPS);
|
||||
}
|
||||
|
||||
$ol_foot = null;
|
||||
if ($oneline) {
|
||||
$ol_foot = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phui-feed-story-oneline-foot'
|
||||
),
|
||||
array(
|
||||
$icon,
|
||||
$foot));
|
||||
}
|
||||
|
||||
$action_list = array();
|
||||
$icons = null;
|
||||
foreach ($this->actions as $action) {
|
||||
|
@ -223,10 +210,9 @@ final class PHUIFeedStoryView extends AphrontView {
|
|||
'class' => 'phui-feed-story-head',
|
||||
),
|
||||
array(
|
||||
(!$oneline ? $actor : null),
|
||||
$actor,
|
||||
nonempty($this->title, pht('Untitled Story')),
|
||||
$icons,
|
||||
$ol_foot
|
||||
));
|
||||
|
||||
if (!empty($this->tokenBar)) {
|
||||
|
@ -249,23 +235,16 @@ final class PHUIFeedStoryView extends AphrontView {
|
|||
$body_content);
|
||||
}
|
||||
|
||||
if ($oneline) {
|
||||
$foot = null;
|
||||
} else {
|
||||
$foot = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phui-feed-story-foot',
|
||||
),
|
||||
array(
|
||||
$icon,
|
||||
$foot));
|
||||
}
|
||||
$foot = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phui-feed-story-foot',
|
||||
),
|
||||
array(
|
||||
$icon,
|
||||
$foot));
|
||||
|
||||
$classes = array('phui-feed-story');
|
||||
if ($oneline) {
|
||||
$classes[] = 'phui-feed-story-oneline';
|
||||
}
|
||||
|
||||
return id(new PHUIBoxView())
|
||||
->addClass(implode(' ', $classes))
|
||||
|
@ -282,6 +261,15 @@ final class PHUIFeedStoryView extends AphrontView {
|
|||
case PhabricatorMacroPHIDTypeMacro::TYPECONST:
|
||||
$this->setAppIcon("macro-dark");
|
||||
break;
|
||||
case ManiphestPHIDTypeTask::TYPECONST:
|
||||
$this->setAppIcon('maniphest-dark');
|
||||
break;
|
||||
case DifferentialPHIDTypeRevision::TYPECONST:
|
||||
$this->setAppIcon('differential-dark');
|
||||
break;
|
||||
case PhabricatorCalendarPHIDTypeEvent::TYPECONST:
|
||||
$this->setAppIcon('calendar-dark');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ final class PHUIObjectItemView extends AphrontTagView {
|
|||
private $imageURI;
|
||||
private $state;
|
||||
private $fontIcon;
|
||||
private $imageIcon;
|
||||
|
||||
const AGE_FRESH = 'fresh';
|
||||
const AGE_STALE = 'stale';
|
||||
|
@ -115,6 +116,15 @@ final class PHUIObjectItemView extends AphrontTagView {
|
|||
return $this->imageURI;
|
||||
}
|
||||
|
||||
public function setImageIcon($image_icon) {
|
||||
$this->imageIcon = $image_icon;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getImageIcon() {
|
||||
return $this->imageIcon;
|
||||
}
|
||||
|
||||
public function setState($state) {
|
||||
$this->state = $state;
|
||||
switch ($state) {
|
||||
|
@ -288,6 +298,10 @@ final class PHUIObjectItemView extends AphrontTagView {
|
|||
$item_classes[] = 'phui-object-item-with-image';
|
||||
}
|
||||
|
||||
if ($this->getImageIcon()) {
|
||||
$item_classes[] = 'phui-object-item-with-image-icon';
|
||||
}
|
||||
|
||||
if ($this->fontIcon) {
|
||||
$item_classes[] = 'phui-object-item-with-ficon';
|
||||
}
|
||||
|
@ -520,6 +534,22 @@ final class PHUIObjectItemView extends AphrontTagView {
|
|||
'style' => 'background-image: url('.$this->getImageURI().')',
|
||||
),
|
||||
'');
|
||||
} else if ($this->getImageIcon()) {
|
||||
$image = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phui-object-item-image-icon',
|
||||
),
|
||||
$this->getImageIcon());
|
||||
}
|
||||
|
||||
if ($image && $this->href) {
|
||||
$image = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $this->href,
|
||||
),
|
||||
$image);
|
||||
}
|
||||
|
||||
$ficon = null;
|
||||
|
|
|
@ -9,20 +9,12 @@ if [ -z "$MXMLC" ]; then
|
|||
fi;
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# cp -R $ROOT/externals/vegas/src $BASEDIR/src/vegas
|
||||
|
||||
(cd $BASEDIR && $MXMLC \
|
||||
-output aphlict.swf \
|
||||
$MXMLC \
|
||||
-output=$ROOT/webroot/rsrc/swf/aphlict.swf \
|
||||
-default-background-color=0x444444 \
|
||||
-default-size=500,500 \
|
||||
-warnings=true \
|
||||
-debug=true \
|
||||
-source-path=$ROOT/externals/vegas/src \
|
||||
-static-link-runtime-shared-libraries=true \
|
||||
src/Aphlict.as)
|
||||
|
||||
mv $BASEDIR/aphlict.swf $ROOT/webroot/rsrc/swf/aphlict.swf
|
||||
|
||||
# -target-player=10.2.0 \
|
||||
$BASEDIR/src/AphlictClient.as
|
||||
|
|
|
@ -1,117 +1,38 @@
|
|||
package {
|
||||
|
||||
import flash.net.*;
|
||||
import flash.utils.*;
|
||||
import flash.media.*;
|
||||
import flash.display.*;
|
||||
import flash.events.*;
|
||||
import flash.display.Sprite;
|
||||
import flash.external.ExternalInterface;
|
||||
import flash.net.LocalConnection;
|
||||
|
||||
import vegas.strings.JSON;
|
||||
|
||||
public class Aphlict extends Sprite {
|
||||
|
||||
private var client:String;
|
||||
/**
|
||||
* A transport channel used to receive data.
|
||||
*/
|
||||
protected var recv:LocalConnection;
|
||||
|
||||
private var socket:Socket;
|
||||
private var readBuffer:ByteArray;
|
||||
/**
|
||||
* A transport channel used to send data.
|
||||
*/
|
||||
protected var send:LocalConnection;
|
||||
|
||||
private var remoteServer:String;
|
||||
private var remotePort:Number;
|
||||
|
||||
public function Aphlict() {
|
||||
super();
|
||||
|
||||
ExternalInterface.addCallback('connect', this.externalConnect);
|
||||
ExternalInterface.call(
|
||||
'JX.Stratcom.invoke',
|
||||
'aphlict-component-ready',
|
||||
null,
|
||||
{});
|
||||
this.recv = new LocalConnection();
|
||||
this.recv.client = this;
|
||||
|
||||
this.send = new LocalConnection();
|
||||
}
|
||||
|
||||
public function externalConnect(server:String, port:Number):void {
|
||||
this.externalInvoke('connect');
|
||||
|
||||
this.remoteServer = server;
|
||||
this.remotePort = port;
|
||||
|
||||
this.connectToServer();
|
||||
}
|
||||
|
||||
|
||||
public function connectToServer():void {
|
||||
var socket:Socket = new Socket();
|
||||
|
||||
socket.addEventListener(Event.CONNECT, didConnectSocket);
|
||||
socket.addEventListener(Event.CLOSE, didCloseSocket);
|
||||
socket.addEventListener(ProgressEvent.SOCKET_DATA, didReceiveSocket);
|
||||
|
||||
socket.addEventListener(IOErrorEvent.IO_ERROR, didIOErrorSocket);
|
||||
socket.addEventListener(
|
||||
SecurityErrorEvent.SECURITY_ERROR,
|
||||
didSecurityErrorSocket);
|
||||
|
||||
socket.connect(this.remoteServer, this.remotePort);
|
||||
|
||||
this.readBuffer = new ByteArray();
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
private function didConnectSocket(event:Event):void {
|
||||
this.externalInvoke('connected');
|
||||
}
|
||||
|
||||
private function didCloseSocket(event:Event):void {
|
||||
this.externalInvoke('close');
|
||||
}
|
||||
|
||||
private function didIOErrorSocket(event:IOErrorEvent):void {
|
||||
this.externalInvoke('error', event.text);
|
||||
}
|
||||
|
||||
private function didSecurityErrorSocket(event:SecurityErrorEvent):void {
|
||||
this.externalInvoke('error', event.text);
|
||||
}
|
||||
|
||||
private function didReceiveSocket(event:Event):void {
|
||||
var b:ByteArray = this.readBuffer;
|
||||
this.socket.readBytes(b, b.length);
|
||||
|
||||
do {
|
||||
b = this.readBuffer;
|
||||
b.position = 0;
|
||||
|
||||
if (b.length <= 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
var msg_len:Number = parseInt(b.readUTFBytes(8), 10);
|
||||
if (b.length >= msg_len + 8) {
|
||||
var bytes:String = b.readUTFBytes(msg_len);
|
||||
var data:Object = vegas.strings.JSON.deserialize(bytes);
|
||||
var t:ByteArray = new ByteArray();
|
||||
t.writeBytes(b, msg_len + 8);
|
||||
this.readBuffer = t;
|
||||
|
||||
this.receiveMessage(data);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
}
|
||||
|
||||
public function receiveMessage(msg:Object):void {
|
||||
this.externalInvoke('receive', msg);
|
||||
}
|
||||
|
||||
public function externalInvoke(type:String, object:Object = null):void {
|
||||
protected function externalInvoke(type:String, object:Object = null):void {
|
||||
ExternalInterface.call('JX.Aphlict.didReceiveEvent', type, object);
|
||||
}
|
||||
|
||||
public function log(message:String):void {
|
||||
ExternalInterface.call('console.log', message);
|
||||
protected function log(message:String):void {
|
||||
this.externalInvoke('log', message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
129
support/aphlict/client/src/AphlictClient.as
Normal file
129
support/aphlict/client/src/AphlictClient.as
Normal file
|
@ -0,0 +1,129 @@
|
|||
package {
|
||||
|
||||
import flash.events.TimerEvent;
|
||||
import flash.external.ExternalInterface;
|
||||
import flash.utils.Timer;
|
||||
|
||||
|
||||
public class AphlictClient extends Aphlict {
|
||||
|
||||
/**
|
||||
* The connection name for this client. This will be used for the
|
||||
* @{class:LocalConnection} object.
|
||||
*/
|
||||
private var client:String;
|
||||
|
||||
/**
|
||||
* The expiry timestamp for the @{class:AphlictMaster}. If this time is
|
||||
* elapsed then the master will be assumed to be dead and another
|
||||
* @{class:AphlictClient} will create a master.
|
||||
*/
|
||||
private var expiry:Number = 0;
|
||||
|
||||
/**
|
||||
* The interval at which to ping the @{class:AphlictMaster}.
|
||||
*/
|
||||
public static const INTERVAL:Number = 3000;
|
||||
|
||||
private var master:AphlictMaster;
|
||||
private var timer:Timer;
|
||||
|
||||
private var remoteServer:String;
|
||||
private var remotePort:Number;
|
||||
|
||||
|
||||
public function AphlictClient() {
|
||||
super();
|
||||
|
||||
ExternalInterface.addCallback('connect', this.externalConnect);
|
||||
ExternalInterface.call(
|
||||
'JX.Stratcom.invoke',
|
||||
'aphlict-component-ready',
|
||||
null,
|
||||
{});
|
||||
}
|
||||
|
||||
public function externalConnect(server:String, port:Number):void {
|
||||
this.externalInvoke('connect');
|
||||
|
||||
this.remoteServer = server;
|
||||
this.remotePort = port;
|
||||
|
||||
this.client = AphlictClient.generateClientId();
|
||||
this.recv.connect(this.client);
|
||||
|
||||
this.timer = new Timer(AphlictClient.INTERVAL);
|
||||
this.timer.addEventListener(TimerEvent.TIMER, this.keepalive);
|
||||
|
||||
this.connectToMaster();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique identifier that will be used to communicate with the
|
||||
* @{class:AphlictMaster}.
|
||||
*/
|
||||
private static function generateClientId():String {
|
||||
return 'aphlict_client_' + Math.round(Math.random() * 100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new connection to the @{class:AphlictMaster}.
|
||||
*
|
||||
* If there is no current @{class:AphlictMaster} instance, then a new master
|
||||
* will be created.
|
||||
*/
|
||||
private function connectToMaster():void {
|
||||
this.timer.stop();
|
||||
|
||||
// Try to become the master.
|
||||
try {
|
||||
this.log('Attempting to become the master...');
|
||||
this.master = new AphlictMaster(this.remoteServer, this.remotePort);
|
||||
this.log('I am the master.');
|
||||
} catch (x:Error) {
|
||||
// Couldn't become the master
|
||||
this.log('Cannot become the master... probably one already exists');
|
||||
}
|
||||
|
||||
this.send.send('aphlict_master', 'register', this.client);
|
||||
this.expiry = new Date().getTime() + (5 * AphlictClient.INTERVAL);
|
||||
this.log('Registered client ' + this.client);
|
||||
|
||||
this.timer.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a keepalive signal to the @{class:AphlictMaster}.
|
||||
*
|
||||
* If the connection to the master has expired (because the master has not
|
||||
* sent a heartbeat signal), then a new connection to master will be
|
||||
* created.
|
||||
*/
|
||||
private function keepalive(event:TimerEvent):void {
|
||||
if (new Date().getTime() > this.expiry) {
|
||||
this.connectToMaster();
|
||||
}
|
||||
|
||||
this.send.send('aphlict_master', 'ping', this.client);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used to receive the heartbeat signal from the
|
||||
* @{class:AphlictMaster}.
|
||||
*/
|
||||
public function pong():void {
|
||||
this.expiry = new Date().getTime() + (2 * AphlictClient.INTERVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a message from the Aphlict Server, via the
|
||||
* @{class:AphlictMaster}.
|
||||
*/
|
||||
public function receiveMessage(msg:Object):void {
|
||||
this.log('Received message.');
|
||||
this.externalInvoke('receive', msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
166
support/aphlict/client/src/AphlictMaster.as
Normal file
166
support/aphlict/client/src/AphlictMaster.as
Normal file
|
@ -0,0 +1,166 @@
|
|||
package {
|
||||
|
||||
import flash.events.Event;
|
||||
import flash.events.IOErrorEvent;
|
||||
import flash.events.ProgressEvent;
|
||||
import flash.events.SecurityErrorEvent;
|
||||
import flash.events.TimerEvent;
|
||||
import flash.net.Socket;
|
||||
import flash.utils.ByteArray;
|
||||
import flash.utils.Dictionary;
|
||||
import flash.utils.Timer;
|
||||
import vegas.strings.JSON;
|
||||
|
||||
|
||||
public class AphlictMaster extends Aphlict {
|
||||
|
||||
/**
|
||||
* The pool of connected clients.
|
||||
*/
|
||||
private var clients:Dictionary;
|
||||
|
||||
/**
|
||||
* A timer used to trigger periodic events.
|
||||
*/
|
||||
private var timer:Timer;
|
||||
|
||||
/**
|
||||
* The interval after which clients will be considered dead and removed
|
||||
* from the pool.
|
||||
*/
|
||||
public static const PURGE_INTERVAL:Number = 3 * AphlictClient.INTERVAL;
|
||||
|
||||
/**
|
||||
* The hostname for the Aphlict Server.
|
||||
*/
|
||||
private var remoteServer:String;
|
||||
|
||||
/**
|
||||
* The port number for the Aphlict Server.
|
||||
*/
|
||||
private var remotePort:Number;
|
||||
|
||||
private var socket:Socket;
|
||||
private var readBuffer:ByteArray;
|
||||
|
||||
|
||||
public function AphlictMaster(server:String, port:Number) {
|
||||
super();
|
||||
|
||||
this.remoteServer = server;
|
||||
this.remotePort = port;
|
||||
|
||||
// Connect to the Aphlict Server.
|
||||
this.recv.connect('aphlict_master');
|
||||
this.connectToServer();
|
||||
|
||||
this.clients = new Dictionary();
|
||||
|
||||
// Start a timer and regularly purge dead clients.
|
||||
this.timer = new Timer(AphlictMaster.PURGE_INTERVAL);
|
||||
this.timer.addEventListener(TimerEvent.TIMER, this.purgeClients);
|
||||
this.timer.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a @{class:AphlictClient}.
|
||||
*/
|
||||
public function register(client:String):void {
|
||||
if (!this.clients[client]) {
|
||||
this.log('Registering client: ' + client);
|
||||
this.clients[client] = new Date().getTime();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge stale client connections from the client pool.
|
||||
*/
|
||||
private function purgeClients(event:TimerEvent):void {
|
||||
for (var client:String in this.clients) {
|
||||
var checkin:Number = this.clients[client];
|
||||
|
||||
if (new Date().getTime() - checkin > AphlictMaster.PURGE_INTERVAL) {
|
||||
this.log('Purging client: ' + client);
|
||||
delete this.clients[client];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clients will regularly "ping" the master to let us know that they are
|
||||
* still alive. We will "pong" them back to let the client know that the
|
||||
* master is still alive.
|
||||
*/
|
||||
public function ping(client:String):void {
|
||||
this.clients[client] = new Date().getTime();
|
||||
this.send.send(client, 'pong');
|
||||
}
|
||||
|
||||
private function connectToServer():void {
|
||||
var socket:Socket = new Socket();
|
||||
|
||||
socket.addEventListener(Event.CONNECT, didConnectSocket);
|
||||
socket.addEventListener(Event.CLOSE, didCloseSocket);
|
||||
socket.addEventListener(ProgressEvent.SOCKET_DATA, didReceiveSocket);
|
||||
|
||||
socket.addEventListener(IOErrorEvent.IO_ERROR, didIOErrorSocket);
|
||||
socket.addEventListener(
|
||||
SecurityErrorEvent.SECURITY_ERROR,
|
||||
didSecurityErrorSocket);
|
||||
|
||||
socket.connect(this.remoteServer, this.remotePort);
|
||||
|
||||
this.readBuffer = new ByteArray();
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
private function didConnectSocket(event:Event):void {
|
||||
this.externalInvoke('connected');
|
||||
}
|
||||
|
||||
private function didCloseSocket(event:Event):void {
|
||||
this.externalInvoke('close');
|
||||
}
|
||||
|
||||
private function didIOErrorSocket(event:IOErrorEvent):void {
|
||||
this.externalInvoke('error', event.text);
|
||||
}
|
||||
|
||||
private function didSecurityErrorSocket(event:SecurityErrorEvent):void {
|
||||
this.externalInvoke('error', event.text);
|
||||
}
|
||||
|
||||
private function didReceiveSocket(event:Event):void {
|
||||
var b:ByteArray = this.readBuffer;
|
||||
this.socket.readBytes(b, b.length);
|
||||
|
||||
do {
|
||||
b = this.readBuffer;
|
||||
b.position = 0;
|
||||
|
||||
if (b.length <= 8) {
|
||||
break;
|
||||
}
|
||||
|
||||
var msg_len:Number = parseInt(b.readUTFBytes(8), 10);
|
||||
if (b.length >= msg_len + 8) {
|
||||
var bytes:String = b.readUTFBytes(msg_len);
|
||||
var data:Object = vegas.strings.JSON.deserialize(bytes);
|
||||
var t:ByteArray = new ByteArray();
|
||||
t.writeBytes(b, msg_len + 8);
|
||||
this.readBuffer = t;
|
||||
|
||||
// Send the message to all clients.
|
||||
for (var client:String in this.clients) {
|
||||
this.log('Sending message to client: ' + client);
|
||||
this.send.send(client, 'receiveMessage', data);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-jump-nav
|
||||
*/
|
||||
|
||||
.phabricator-jump-nav-form {
|
||||
text-align: center;
|
||||
padding: 0px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input.phabricator-jump-nav[type='text'] {
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.phabricator-jump-nav-caption {
|
||||
margin-top: 4px;
|
||||
font-size: 11px;
|
||||
color: {$greytext};
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.phabricator-jump-nav-container form {
|
||||
padding: 12px 16px;
|
||||
}
|
|
@ -671,3 +671,54 @@
|
|||
border: none;
|
||||
border-bottom: 1px solid {$thinblueborder};
|
||||
}
|
||||
|
||||
|
||||
/* - Launcher List ---------------------------------------------------------- */
|
||||
|
||||
.launcher-header {
|
||||
margin: 8px 16px -4px;
|
||||
clear: both;
|
||||
color: {$darkbluetext};
|
||||
}
|
||||
|
||||
.launcher-header:nth-of-type(1) {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.phui-object-item-launcher-list {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.device-desktop .phui-object-item-launcher-list .phui-object-item {
|
||||
width: 32.333%;
|
||||
float: left;
|
||||
margin-right: 1%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.phui-object-item-image-icon {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.phui-object-item-image-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 4px 4px 4px 4px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.phui-object-item-image-icon .phui-icon-view {
|
||||
position: absolute;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
left: 6px;
|
||||
top: 6px;
|
||||
}
|
||||
|
||||
.phui-object-item-with-image-icon .phui-object-item-frame {
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.phui-object-item-with-image-icon .phui-object-item-content-box {
|
||||
margin-left: 44px;
|
||||
}
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue