1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 08:42: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:
Bob Trahan 2013-02-04 19:01:46 -08:00
parent 112c2ebfbe
commit a211f97737
11 changed files with 304 additions and 91 deletions

View file

@ -166,7 +166,7 @@ abstract class ConpherenceController extends PhabricatorController {
private function getNoConpherencesBlock() { private function getNoConpherencesBlock() {
return phutil_render_tag( return phutil_tag(
'div', 'div',
array( array(
'class' => 'no-conpherences-menu-item' 'class' => 'no-conpherences-menu-item'

View file

@ -65,51 +65,55 @@ final class ConpherenceListController extends
private function renderEmptyMainPane() { private function renderEmptyMainPane() {
$this->initJavelinBehaviors(); $this->initJavelinBehaviors();
return phutil_render_tag( return phutil_tag(
'div', 'div',
array( array(
'id' => 'conpherence-main-pane' 'id' => 'conpherence-main-pane'
), ),
phutil_render_tag( array(
'div', phutil_tag(
array(
'class' => 'conpherence-header-pane',
'id' => 'conpherence-header-pane',
),
''
).
phutil_render_tag(
'div',
array(
'class' => 'conpherence-widget-pane',
'id' => 'conpherence-widget-pane'
),
''
).
javelin_render_tag(
'div',
array(
'class' => 'conpherence-message-pane',
'id' => 'conpherence-message-pane'
),
phutil_render_tag(
'div', 'div',
array( array(
'class' => 'conpherence-messages', 'class' => 'conpherence-header-pane',
'id' => 'conpherence-messages' 'id' => 'conpherence-header-pane',
), ),
'' ''
). ),
phutil_render_tag( phutil_tag(
'div', 'div',
array( array(
'id' => 'conpherence-form' 'class' => 'conpherence-widget-pane',
'id' => 'conpherence-widget-pane'
), ),
'' ''
),
javelin_tag(
'div',
array(
'class' => 'conpherence-message-pane',
'id' => 'conpherence-message-pane'
),
array(
phutil_tag(
'div',
array(
'class' => 'conpherence-messages',
'id' => 'conpherence-messages'
),
''
),
phutil_tag(
'div',
array(
'id' => 'conpherence-form'
),
''
)
)
) )
) )
); );
} }
} }

View file

@ -92,7 +92,7 @@ final class ConpherenceNewController extends ConpherenceController {
->setTitle('Success') ->setTitle('Success')
->addCancelButton('#', 'Okay') ->addCancelButton('#', 'Okay')
->appendChild( ->appendChild(
phutil_render_tag('p', phutil_tag('p',
array(), array(),
pht('Message sent successfully.') pht('Message sent successfully.')
) )

View file

@ -135,7 +135,7 @@ final class ConpherenceUpdateController extends
->appendChild( ->appendChild(
id(new AphrontFormMarkupControl()) id(new AphrontFormMarkupControl())
->setLabel(pht('Image')) ->setLabel(pht('Image'))
->setValue(phutil_render_tag( ->setValue(phutil_tag(
'img', 'img',
array( array(
'src' => $conpherence->loadImageURI(), 'src' => $conpherence->loadImageURI(),

View file

@ -71,7 +71,7 @@ final class ConpherenceViewController extends
$edit_href = $this->getApplicationURI('update/'.$conpherence->getID().'/'); $edit_href = $this->getApplicationURI('update/'.$conpherence->getID().'/');
$header = $header =
javelin_render_tag( javelin_tag(
'a', 'a',
array( array(
'class' => 'edit', 'class' => 'edit',
@ -80,7 +80,7 @@ final class ConpherenceViewController extends
), ),
'' ''
). ).
phutil_render_tag( phutil_tag(
'div', 'div',
array( array(
'class' => 'header-image', 'class' => 'header-image',
@ -88,19 +88,19 @@ final class ConpherenceViewController extends
), ),
'' ''
). ).
phutil_render_tag( phutil_tag(
'div', 'div',
array( array(
'class' => 'title', 'class' => 'title',
), ),
phutil_escape_html($display_data['title']) $display_data['title']
). ).
phutil_render_tag( phutil_tag(
'div', 'div',
array( array(
'class' => 'subtitle', 'class' => 'subtitle',
), ),
phutil_escape_html($display_data['subtitle']) $display_data['subtitle']
); );
return array('header' => $header); return array('header' => $header);
@ -152,6 +152,7 @@ final class ConpherenceViewController extends
private function renderWidgetPaneContent() { private function renderWidgetPaneContent() {
require_celerity_resource('conpherence-widget-pane-css'); require_celerity_resource('conpherence-widget-pane-css');
require_celerity_resource('sprite-conpher-css');
Javelin::initBehavior( Javelin::initBehavior(
'conpherence-widget-pane', 'conpherence-widget-pane',
array( array(
@ -165,37 +166,54 @@ final class ConpherenceViewController extends
$conpherence = $this->getConpherence(); $conpherence = $this->getConpherence();
$widgets = phutil_render_tag( $widgets = phutil_tag(
'div', 'div',
array( array(
'class' => 'widgets-header' 'class' => 'widgets-header'
), ),
javelin_render_tag( array(
'a', javelin_tag(
array( 'a',
'sigil' => 'conpherence-change-widget', array(
'meta' => array('widget' => 'widgets-files') 'sigil' => 'conpherence-change-widget',
'meta' => array(
'widget' => 'widgets-files',
'toggleClass' => 'conpher_files_on'
),
'id' => 'widgets-files-toggle',
'class' => 'sprite-conpher conpher_files_off first-icon'
),
''
), ),
pht('Files') javelin_tag(
).' | '. 'a',
javelin_render_tag( array(
'a', 'sigil' => 'conpherence-change-widget',
array( 'meta' => array(
'sigil' => 'conpherence-change-widget', 'widget' => 'widgets-tasks',
'meta' => array('widget' => 'widgets-tasks') 'toggleClass' => 'conpher_list_on'
),
'id' => 'widgets-tasks-toggle',
'class' => 'sprite-conpher conpher_list_off conpher_list_on',
),
''
), ),
pht('Tasks') javelin_tag(
).' | '. 'a',
javelin_render_tag( array(
'a', 'sigil' => 'conpherence-change-widget',
array( 'meta' => array(
'sigil' => 'conpherence-change-widget', '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', 'div',
array( array(
'class' => 'widgets-body', 'class' => 'widgets-body',
@ -204,7 +222,7 @@ final class ConpherenceViewController extends
), ),
$this->renderFilesWidgetPaneContent() $this->renderFilesWidgetPaneContent()
). ).
phutil_render_tag( phutil_tag(
'div', 'div',
array( array(
'class' => 'widgets-body', 'class' => 'widgets-body',
@ -212,7 +230,7 @@ final class ConpherenceViewController extends
), ),
$this->renderTaskWidgetPaneContent() $this->renderTaskWidgetPaneContent()
). ).
phutil_render_tag( phutil_tag(
'div', 'div',
array( array(
'class' => 'widgets-body', 'class' => 'widgets-body',
@ -234,7 +252,7 @@ final class ConpherenceViewController extends
foreach ($files as $file) { foreach ($files as $file) {
$thumb = $file->getThumb60x45URI(); $thumb = $file->getThumb60x45URI();
$table_data[] = array( $table_data[] = array(
phutil_render_tag( phutil_tag(
'img', 'img',
array( array(
'src' => $thumb 'src' => $thumb
@ -250,7 +268,7 @@ final class ConpherenceViewController extends
->setNoDataString(pht('No files attached to conpherence.')) ->setNoDataString(pht('No files attached to conpherence.'))
->setHeaders(array('', pht('Name'))) ->setHeaders(array('', pht('Name')))
->setColumnClasses(array('', 'wide')); ->setColumnClasses(array('', 'wide'));
return $header->render() . $table->render(); return new PhutilSafeHTML($header->render() . $table->render());
} }
private function renderTaskWidgetPaneContent() { private function renderTaskWidgetPaneContent() {
@ -271,12 +289,12 @@ final class ConpherenceViewController extends
foreach ($actual_tasks as $task) { foreach ($actual_tasks as $task) {
$data[] = array( $data[] = array(
idx($priority_map, $task->getPriority(), pht('???')), idx($priority_map, $task->getPriority(), pht('???')),
phutil_render_tag( phutil_tag(
'a', 'a',
array( array(
'href' => '/T'.$task->getID() 'href' => '/T'.$task->getID()
), ),
phutil_escape_html($task->getTitle()) $task->getTitle()
) )
); );
} }
@ -286,13 +304,110 @@ final class ConpherenceViewController extends
->setColumnClasses(array('', 'wide')); ->setColumnClasses(array('', 'wide'));
$content[] = $table->render(); $content[] = $table->render();
} }
return implode('', $content); return new PhutilSafeHTML(implode('', $content));
} }
private function renderCalendarWidgetPaneContent() { private function renderCalendarWidgetPaneContent() {
$header = id(new PhabricatorHeaderView()) $user = $this->getRequest()->getUser();
->setHeader(pht('Calendar'));
return $header->render() . 'TODO'; $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;
} }
} }

View file

@ -141,17 +141,22 @@ final class ConpherenceThreadQuery
$tasks = mgroup($tasks, 'getOwnerPHID'); $tasks = mgroup($tasks, 'getOwnerPHID');
// statuses of everyone currently in the conpherence // statuses of everyone currently in the conpherence
// until the beginning of the next work week. // for a rolling one week window
// NOTE: this is a bit boring on the weekends. $start_of_week = phabricator_format_local_time(
strtotime('today'),
$this->getViewer(),
'U'
);
$end_of_week = phabricator_format_local_time( $end_of_week = phabricator_format_local_time(
strtotime('Monday midnight'), strtotime('midnight +1 week'),
$this->getViewer(), $this->getViewer(),
'U' 'U'
); );
$statuses = id(new PhabricatorUserStatus()) $statuses = id(new PhabricatorUserStatus())
->loadAllWhere( ->loadAllWhere(
'userPHID in (%Ls) AND dateTo <= %d', 'userPHID in (%Ls) AND dateTo >= %d AND dateFrom <= %d',
$participant_phids, $participant_phids,
$start_of_week,
$end_of_week $end_of_week
); );
$statuses = mgroup($statuses, 'getUserPHID'); $statuses = mgroup($statuses, 'getUserPHID');
@ -168,9 +173,12 @@ final class ConpherenceThreadQuery
foreach ($conpherences as $phid => $conpherence) { foreach ($conpherences as $phid => $conpherence) {
$participant_phids = array_keys($conpherence->getParticipants()); $participant_phids = array_keys($conpherence->getParticipants());
$statuses = array_select_keys($statuses, $participant_phids);
$statuses = array_mergev($statuses);
$statuses = msort($statuses, 'getDateFrom');
$widget_data = array( $widget_data = array(
'tasks' => array_select_keys($tasks, $participant_phids), 'tasks' => array_select_keys($tasks, $participant_phids),
'statuses' => array_select_keys($statuses, $participant_phids), 'statuses' => $statuses,
'files' => array_select_keys($files, $conpherence->getFilePHIDs()), 'files' => array_select_keys($files, $conpherence->getFilePHIDs()),
); );
$conpherence->attachWidgetData($widget_data); $conpherence->attachWidgetData($widget_data);

View file

@ -85,7 +85,7 @@ final class ConpherenceMenuItemView extends AphrontTagView {
protected function getTagContent() { protected function getTagContent() {
$image = null; $image = null;
if ($this->imageURI) { if ($this->imageURI) {
$image = phutil_render_tag( $image = phutil_tag(
'span', 'span',
array( array(
'class' => 'conpherence-menu-item-image', 'class' => 'conpherence-menu-item-image',
@ -95,34 +95,34 @@ final class ConpherenceMenuItemView extends AphrontTagView {
} }
$title = null; $title = null;
if ($this->title) { if ($this->title) {
$title = phutil_render_tag( $title = phutil_tag(
'span', 'span',
array( array(
'class' => 'conpherence-menu-item-title', 'class' => 'conpherence-menu-item-title',
), ),
phutil_escape_html($this->title)); $this->title);
} }
$subtitle = null; $subtitle = null;
if ($this->subtitle) { if ($this->subtitle) {
$subtitle = phutil_render_tag( $subtitle = phutil_tag(
'span', 'span',
array( array(
'class' => 'conpherence-menu-item-subtitle', 'class' => 'conpherence-menu-item-subtitle',
), ),
phutil_escape_html($this->subtitle)); $this->subtitle);
} }
$message = null; $message = null;
if ($this->messageText) { if ($this->messageText) {
$message = phutil_render_tag( $message = phutil_tag(
'span', 'span',
array( array(
'class' => 'conpherence-menu-item-message-text' 'class' => 'conpherence-menu-item-message-text'
), ),
phutil_escape_html($this->messageText)); $this->messageText);
} }
$epoch = null; $epoch = null;
if ($this->epoch) { if ($this->epoch) {
$epoch = phutil_render_tag( $epoch = phutil_tag(
'span', 'span',
array( array(
'class' => 'conpherence-menu-item-date', 'class' => 'conpherence-menu-item-date',
@ -131,7 +131,7 @@ final class ConpherenceMenuItemView extends AphrontTagView {
} }
$unread_count = null; $unread_count = null;
if ($this->unreadCount) { if ($this->unreadCount) {
$unread_count = phutil_render_tag( $unread_count = phutil_tag(
'span', 'span',
array( array(
'class' => 'conpherence-menu-item-unread-count' 'class' => 'conpherence-menu-item-unread-count'

View file

@ -47,7 +47,7 @@ final class ConpherenceTransactionView extends AphrontView {
case ConpherenceTransactionType::TYPE_PICTURE: case ConpherenceTransactionType::TYPE_PICTURE:
$img = $transaction->getHandle($transaction->getNewValue()); $img = $transaction->getHandle($transaction->getNewValue());
$content = $transaction->getTitle() . $content = $transaction->getTitle() .
phutil_render_tag( phutil_tag(
'img', 'img',
array( array(
'src' => $img->getImageURI() 'src' => $img->getImageURI()
@ -85,12 +85,12 @@ final class ConpherenceTransactionView extends AphrontView {
} }
$transaction_view $transaction_view
->appendChild(phutil_render_tag( ->appendChild(phutil_tag(
'div', 'div',
array( array(
'class' => $content_class 'class' => $content_class
), ),
$content) new PhutilSafeHTML($content))
); );
return $transaction_view->render(); return $transaction_view->render();

View file

@ -12,9 +12,88 @@
border-color: #CCC; border-color: #CCC;
border-style: solid; border-style: solid;
background: url('/rsrc/image/texture/dust_background.jpg'); background: url('/rsrc/image/texture/dust_background.jpg');
overflow-y: auto;
} }
.conpherence-widget-pane .aphront-form-input { .conpherence-widget-pane .aphront-form-input {
margin: 0; margin: 0;
width: 100%; 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;
}

View file

@ -4,7 +4,7 @@
*/ */
.sprite-conpher { .sprite-conpher {
background-image: url(/rsrc/image/sprite-conpher.png); background-image: url(/rsrc/image/sprite-conph.png);
background-repeat: no-repeat; background-repeat: no-repeat;
} }
@ -12,7 +12,7 @@
only screen and (min-device-pixel-ratio: 1.5), only screen and (min-device-pixel-ratio: 1.5),
only screen and (-webkit-min-device-pixel-ratio: 1.5) { only screen and (-webkit-min-device-pixel-ratio: 1.5) {
.sprite-conpher { .sprite-conpher {
background-image: url(/rsrc/image/sprite-conpher-X2.png); background-image: url(/rsrc/image/sprite-conph-X2.png);
background-size: 132px 132px; background-size: 132px 132px;
} }
} }

View file

@ -16,8 +16,15 @@ JX.behavior('conpherence-widget-pane', function(config) {
for (var widget in config.widgetRegistery) { for (var widget in config.widgetRegistery) {
if (widget == data.widget) { if (widget == data.widget) {
JX.$(widget).style.display = 'block'; JX.$(widget).style.display = 'block';
JX.DOM.alterClass(e.getTarget(), data.toggleClass, true);
} else { } else {
JX.$(widget).style.display = 'none'; JX.$(widget).style.display = 'none';
var cur_toggle = JX.$(widget + '-toggle');
JX.DOM.alterClass(
cur_toggle,
JX.Stratcom.getData(cur_toggle).toggleClass,
false
);
} }
} }
} }