mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 18:22:41 +01:00
Conpherence - some widget and display stuff
Summary: this was originally "just" adding the icons like I had bundled into D4790. It morphed a bit though and does a few things - adds the icons - cleans up widget CSS generally a bit so scrolling always works - phutil_tag -- probably was a bad idea but I wanted to play with it. I think its harder to not break conpherence when you land the branch now maybs. Still up for fixing it immediately post land though. Test Plan: played with conphernece a bit. Used FF and Chrome to verify CSS was looking okay-ish. Reviewers: epriestley, chad Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T2399 Differential Revision: https://secure.phabricator.com/D4814
This commit is contained in:
parent
112c2ebfbe
commit
a211f97737
11 changed files with 304 additions and 91 deletions
|
@ -166,7 +166,7 @@ abstract class ConpherenceController extends PhabricatorController {
|
|||
|
||||
private function getNoConpherencesBlock() {
|
||||
|
||||
return phutil_render_tag(
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'no-conpherences-menu-item'
|
||||
|
|
|
@ -65,42 +65,44 @@ final class ConpherenceListController extends
|
|||
|
||||
private function renderEmptyMainPane() {
|
||||
$this->initJavelinBehaviors();
|
||||
return phutil_render_tag(
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => 'conpherence-main-pane'
|
||||
),
|
||||
phutil_render_tag(
|
||||
array(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'conpherence-header-pane',
|
||||
'id' => 'conpherence-header-pane',
|
||||
),
|
||||
''
|
||||
).
|
||||
phutil_render_tag(
|
||||
),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'conpherence-widget-pane',
|
||||
'id' => 'conpherence-widget-pane'
|
||||
),
|
||||
''
|
||||
).
|
||||
javelin_render_tag(
|
||||
),
|
||||
javelin_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'conpherence-message-pane',
|
||||
'id' => 'conpherence-message-pane'
|
||||
),
|
||||
phutil_render_tag(
|
||||
array(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'conpherence-messages',
|
||||
'id' => 'conpherence-messages'
|
||||
),
|
||||
''
|
||||
).
|
||||
phutil_render_tag(
|
||||
),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => 'conpherence-form'
|
||||
|
@ -108,8 +110,10 @@ final class ConpherenceListController extends
|
|||
''
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ final class ConpherenceNewController extends ConpherenceController {
|
|||
->setTitle('Success')
|
||||
->addCancelButton('#', 'Okay')
|
||||
->appendChild(
|
||||
phutil_render_tag('p',
|
||||
phutil_tag('p',
|
||||
array(),
|
||||
pht('Message sent successfully.')
|
||||
)
|
||||
|
|
|
@ -135,7 +135,7 @@ final class ConpherenceUpdateController extends
|
|||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel(pht('Image'))
|
||||
->setValue(phutil_render_tag(
|
||||
->setValue(phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
'src' => $conpherence->loadImageURI(),
|
||||
|
|
|
@ -71,7 +71,7 @@ final class ConpherenceViewController extends
|
|||
$edit_href = $this->getApplicationURI('update/'.$conpherence->getID().'/');
|
||||
|
||||
$header =
|
||||
javelin_render_tag(
|
||||
javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'edit',
|
||||
|
@ -80,7 +80,7 @@ final class ConpherenceViewController extends
|
|||
),
|
||||
''
|
||||
).
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'header-image',
|
||||
|
@ -88,19 +88,19 @@ final class ConpherenceViewController extends
|
|||
),
|
||||
''
|
||||
).
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'title',
|
||||
),
|
||||
phutil_escape_html($display_data['title'])
|
||||
$display_data['title']
|
||||
).
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'subtitle',
|
||||
),
|
||||
phutil_escape_html($display_data['subtitle'])
|
||||
$display_data['subtitle']
|
||||
);
|
||||
|
||||
return array('header' => $header);
|
||||
|
@ -152,6 +152,7 @@ final class ConpherenceViewController extends
|
|||
|
||||
private function renderWidgetPaneContent() {
|
||||
require_celerity_resource('conpherence-widget-pane-css');
|
||||
require_celerity_resource('sprite-conpher-css');
|
||||
Javelin::initBehavior(
|
||||
'conpherence-widget-pane',
|
||||
array(
|
||||
|
@ -165,37 +166,54 @@ final class ConpherenceViewController extends
|
|||
|
||||
$conpherence = $this->getConpherence();
|
||||
|
||||
$widgets = phutil_render_tag(
|
||||
$widgets = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'widgets-header'
|
||||
),
|
||||
javelin_render_tag(
|
||||
array(
|
||||
javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'sigil' => 'conpherence-change-widget',
|
||||
'meta' => array('widget' => 'widgets-files')
|
||||
'meta' => array(
|
||||
'widget' => 'widgets-files',
|
||||
'toggleClass' => 'conpher_files_on'
|
||||
),
|
||||
pht('Files')
|
||||
).' | '.
|
||||
javelin_render_tag(
|
||||
'id' => 'widgets-files-toggle',
|
||||
'class' => 'sprite-conpher conpher_files_off first-icon'
|
||||
),
|
||||
''
|
||||
),
|
||||
javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'sigil' => 'conpherence-change-widget',
|
||||
'meta' => array('widget' => 'widgets-tasks')
|
||||
'meta' => array(
|
||||
'widget' => 'widgets-tasks',
|
||||
'toggleClass' => 'conpher_list_on'
|
||||
),
|
||||
pht('Tasks')
|
||||
).' | '.
|
||||
javelin_render_tag(
|
||||
'id' => 'widgets-tasks-toggle',
|
||||
'class' => 'sprite-conpher conpher_list_off conpher_list_on',
|
||||
),
|
||||
''
|
||||
),
|
||||
javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'sigil' => 'conpherence-change-widget',
|
||||
'meta' => array('widget' => 'widgets-calendar')
|
||||
'meta' => array(
|
||||
'widget' => 'widgets-calendar',
|
||||
'toggleClass' => 'conpher_calendar_on'
|
||||
),
|
||||
pht('Calendar')
|
||||
'id' => 'widgets-calendar-toggle',
|
||||
'class' => 'sprite-conpher conpher_calendar_off',
|
||||
),
|
||||
''
|
||||
)
|
||||
)
|
||||
).
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'widgets-body',
|
||||
|
@ -204,7 +222,7 @@ final class ConpherenceViewController extends
|
|||
),
|
||||
$this->renderFilesWidgetPaneContent()
|
||||
).
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'widgets-body',
|
||||
|
@ -212,7 +230,7 @@ final class ConpherenceViewController extends
|
|||
),
|
||||
$this->renderTaskWidgetPaneContent()
|
||||
).
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'widgets-body',
|
||||
|
@ -234,7 +252,7 @@ final class ConpherenceViewController extends
|
|||
foreach ($files as $file) {
|
||||
$thumb = $file->getThumb60x45URI();
|
||||
$table_data[] = array(
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
'src' => $thumb
|
||||
|
@ -250,7 +268,7 @@ final class ConpherenceViewController extends
|
|||
->setNoDataString(pht('No files attached to conpherence.'))
|
||||
->setHeaders(array('', pht('Name')))
|
||||
->setColumnClasses(array('', 'wide'));
|
||||
return $header->render() . $table->render();
|
||||
return new PhutilSafeHTML($header->render() . $table->render());
|
||||
}
|
||||
|
||||
private function renderTaskWidgetPaneContent() {
|
||||
|
@ -271,12 +289,12 @@ final class ConpherenceViewController extends
|
|||
foreach ($actual_tasks as $task) {
|
||||
$data[] = array(
|
||||
idx($priority_map, $task->getPriority(), pht('???')),
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/T'.$task->getID()
|
||||
),
|
||||
phutil_escape_html($task->getTitle())
|
||||
$task->getTitle()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -286,13 +304,110 @@ final class ConpherenceViewController extends
|
|||
->setColumnClasses(array('', 'wide'));
|
||||
$content[] = $table->render();
|
||||
}
|
||||
return implode('', $content);
|
||||
return new PhutilSafeHTML(implode('', $content));
|
||||
}
|
||||
|
||||
private function renderCalendarWidgetPaneContent() {
|
||||
$header = id(new PhabricatorHeaderView())
|
||||
->setHeader(pht('Calendar'));
|
||||
return $header->render() . 'TODO';
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$conpherence = $this->getConpherence();
|
||||
$widget_data = $conpherence->getWidgetData();
|
||||
$statuses = $widget_data['statuses'];
|
||||
$handles = $conpherence->getHandles();
|
||||
$content = array();
|
||||
$timestamps = $this->getCalendarWidgetWeekTimestamps();
|
||||
$one_day = 24 * 60 * 60;
|
||||
foreach ($timestamps as $time => $day) {
|
||||
// build a header for the new day
|
||||
$content[] = id(new PhabricatorHeaderView())
|
||||
->setHeader($day->format('l'))
|
||||
->render();
|
||||
|
||||
$day->setTime(0, 0, 0);
|
||||
$epoch_start = $day->format('U');
|
||||
$day->modify('+1 day');
|
||||
$epoch_end = $day->format('U');
|
||||
|
||||
// keep looking through statuses where we last left off
|
||||
foreach ($statuses as $status) {
|
||||
if ($status->getDateFrom() >= $epoch_end) {
|
||||
// This list is sorted, so we can stop looking.
|
||||
break;
|
||||
}
|
||||
if ($status->getDateFrom() < $epoch_end &&
|
||||
$status->getDateTo() > $epoch_start) {
|
||||
$timespan = $status->getDateTo() - $status->getDateFrom();
|
||||
if ($timespan > $one_day) {
|
||||
$time_str = 'm/d';
|
||||
} else {
|
||||
$time_str = 'h:i A';
|
||||
}
|
||||
$epoch_range = phabricator_format_local_time(
|
||||
$status->getDateFrom(),
|
||||
$user,
|
||||
$time_str
|
||||
) . ' - ' . phabricator_format_local_time(
|
||||
$status->getDateTo(),
|
||||
$user,
|
||||
$time_str
|
||||
);
|
||||
|
||||
$content[] = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'user-status '.$status->getTextStatus(),
|
||||
),
|
||||
array(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'epoch-range'
|
||||
),
|
||||
$epoch_range
|
||||
),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'icon',
|
||||
),
|
||||
''
|
||||
),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'description'
|
||||
),
|
||||
$status->getTerseSummary($user)
|
||||
),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'participant'
|
||||
),
|
||||
$handles[$status->getUserPHID()]->getName()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new PhutilSafeHTML(implode('', $content));
|
||||
}
|
||||
|
||||
private function getCalendarWidgetWeekTimestamps() {
|
||||
$user = $this->getRequest()->getUser();
|
||||
$timezone = new DateTimeZone($user->getTimezoneIdentifier());
|
||||
|
||||
$timestamps = array();
|
||||
for ($day = 0; $day < 7; $day++) {
|
||||
$timestamps[] = new DateTime(
|
||||
sprintf('today +%d days', $day),
|
||||
$timezone
|
||||
);
|
||||
}
|
||||
|
||||
return $timestamps;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,7 +85,7 @@ final class ConpherenceMenuItemView extends AphrontTagView {
|
|||
protected function getTagContent() {
|
||||
$image = null;
|
||||
if ($this->imageURI) {
|
||||
$image = phutil_render_tag(
|
||||
$image = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'conpherence-menu-item-image',
|
||||
|
@ -95,34 +95,34 @@ final class ConpherenceMenuItemView extends AphrontTagView {
|
|||
}
|
||||
$title = null;
|
||||
if ($this->title) {
|
||||
$title = phutil_render_tag(
|
||||
$title = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'conpherence-menu-item-title',
|
||||
),
|
||||
phutil_escape_html($this->title));
|
||||
$this->title);
|
||||
}
|
||||
$subtitle = null;
|
||||
if ($this->subtitle) {
|
||||
$subtitle = phutil_render_tag(
|
||||
$subtitle = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'conpherence-menu-item-subtitle',
|
||||
),
|
||||
phutil_escape_html($this->subtitle));
|
||||
$this->subtitle);
|
||||
}
|
||||
$message = null;
|
||||
if ($this->messageText) {
|
||||
$message = phutil_render_tag(
|
||||
$message = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'conpherence-menu-item-message-text'
|
||||
),
|
||||
phutil_escape_html($this->messageText));
|
||||
$this->messageText);
|
||||
}
|
||||
$epoch = null;
|
||||
if ($this->epoch) {
|
||||
$epoch = phutil_render_tag(
|
||||
$epoch = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'conpherence-menu-item-date',
|
||||
|
@ -131,7 +131,7 @@ final class ConpherenceMenuItemView extends AphrontTagView {
|
|||
}
|
||||
$unread_count = null;
|
||||
if ($this->unreadCount) {
|
||||
$unread_count = phutil_render_tag(
|
||||
$unread_count = phutil_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'conpherence-menu-item-unread-count'
|
||||
|
|
|
@ -47,7 +47,7 @@ final class ConpherenceTransactionView extends AphrontView {
|
|||
case ConpherenceTransactionType::TYPE_PICTURE:
|
||||
$img = $transaction->getHandle($transaction->getNewValue());
|
||||
$content = $transaction->getTitle() .
|
||||
phutil_render_tag(
|
||||
phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
'src' => $img->getImageURI()
|
||||
|
@ -85,12 +85,12 @@ final class ConpherenceTransactionView extends AphrontView {
|
|||
}
|
||||
|
||||
$transaction_view
|
||||
->appendChild(phutil_render_tag(
|
||||
->appendChild(phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => $content_class
|
||||
),
|
||||
$content)
|
||||
new PhutilSafeHTML($content))
|
||||
);
|
||||
|
||||
return $transaction_view->render();
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue