1
0
Fork 0
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:
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() {
return phutil_render_tag(
return phutil_tag(
'div',
array(
'class' => 'no-conpherences-menu-item'

View file

@ -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
''
)
)
)
)
);
}
}
}

View file

@ -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.')
)

View file

@ -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(),

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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'

View file

@ -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();

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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
);
}
}
}