mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Conpherence - implement join / view rules for rooms
Summary: Ref T7585. This implements everything specified, with a few caveats - since rooms you have yet to join can't be viewed in the column yet, the column view has some bugs and isn't expected to work. - the room you're looking at is just pre-pending to the top of the "recent" list Test Plan: made a room that no one could join. verified when viewing that there was no comment ui. made a room that others could join. verified folks who had yet to join had a "join" button with an area for text. tried joining with / without message text and it worked in both cases Reviewers: chad, epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7585 Differential Revision: https://secure.phabricator.com/D12149
This commit is contained in:
parent
aa310230b6
commit
25767096c9
11 changed files with 178 additions and 62 deletions
|
@ -49,7 +49,7 @@ return array(
|
|||
'rsrc/css/application/conpherence/message-pane.css' => 'e78e9d3c',
|
||||
'rsrc/css/application/conpherence/notification.css' => '04a6e10a',
|
||||
'rsrc/css/application/conpherence/update.css' => '1099a660',
|
||||
'rsrc/css/application/conpherence/widget-pane.css' => '9efbfed0',
|
||||
'rsrc/css/application/conpherence/widget-pane.css' => '9199d87c',
|
||||
'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
|
||||
'rsrc/css/application/countdown/timer.css' => '86b7b0a0',
|
||||
'rsrc/css/application/dashboard/dashboard.css' => '17937d22',
|
||||
|
@ -354,7 +354,7 @@ return array(
|
|||
'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de',
|
||||
'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '24561adb',
|
||||
'rsrc/js/application/conpherence/behavior-durable-column.js' => 'eedc463c',
|
||||
'rsrc/js/application/conpherence/behavior-menu.js' => 'c4151295',
|
||||
'rsrc/js/application/conpherence/behavior-menu.js' => 'be9207ed',
|
||||
'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861',
|
||||
'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3',
|
||||
'rsrc/js/application/conpherence/behavior-widget-pane.js' => '2c1cd7f5',
|
||||
|
@ -519,7 +519,7 @@ return array(
|
|||
'conpherence-notification-css' => '04a6e10a',
|
||||
'conpherence-thread-manager' => '24561adb',
|
||||
'conpherence-update-css' => '1099a660',
|
||||
'conpherence-widget-pane-css' => '9efbfed0',
|
||||
'conpherence-widget-pane-css' => '9199d87c',
|
||||
'differential-changeset-view-css' => '79c27a4c',
|
||||
'differential-core-view-css' => '7ac3cabc',
|
||||
'differential-inline-comment-editor' => 'f2431bc1',
|
||||
|
@ -556,7 +556,7 @@ return array(
|
|||
'javelin-behavior-boards-dropdown' => '0ec56e1d',
|
||||
'javelin-behavior-choose-control' => '6153c708',
|
||||
'javelin-behavior-config-reorder-fields' => '14a827de',
|
||||
'javelin-behavior-conpherence-menu' => 'c4151295',
|
||||
'javelin-behavior-conpherence-menu' => 'be9207ed',
|
||||
'javelin-behavior-conpherence-pontificate' => '21ba5861',
|
||||
'javelin-behavior-conpherence-widget-pane' => '2c1cd7f5',
|
||||
'javelin-behavior-countdown-timer' => 'e4cc26b3',
|
||||
|
@ -1718,14 +1718,7 @@ return array(
|
|||
'javelin-util',
|
||||
'phabricator-shaped-request',
|
||||
),
|
||||
'c1700f6f' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'c4151295' => array(
|
||||
'be9207ed' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
|
@ -1737,6 +1730,13 @@ return array(
|
|||
'phabricator-shaped-request',
|
||||
'conpherence-thread-manager',
|
||||
),
|
||||
'c1700f6f' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
),
|
||||
'c51ae228' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-util',
|
||||
|
|
|
@ -5,6 +5,7 @@ final class ConpherenceUpdateActions extends ConpherenceConstants {
|
|||
const METADATA = 'metadata';
|
||||
const MESSAGE = 'message';
|
||||
const DRAFT = 'draft';
|
||||
const JOIN_ROOM = 'join_room';
|
||||
const ADD_PERSON = 'add_person';
|
||||
const REMOVE_PERSON = 'remove_person';
|
||||
const NOTIFICATIONS = 'notifications';
|
||||
|
|
|
@ -69,11 +69,23 @@ final class ConpherenceListController extends ConpherenceController {
|
|||
if ($conpherence->getTitle()) {
|
||||
$title = $conpherence->getTitle();
|
||||
}
|
||||
$cursor = $conpherence->getParticipant($user->getPHID());
|
||||
$data = $this->loadParticipationWithMidCursor($cursor);
|
||||
$all_participation = $data['participation'];
|
||||
$scroll_up_participant = $data['scroll_up_participant'];
|
||||
$scroll_down_participant = $data['scroll_down_participant'];
|
||||
$cursor = $conpherence->getParticipantIfExists($user->getPHID());
|
||||
if ($cursor) {
|
||||
$data = $this->loadParticipationWithMidCursor($cursor);
|
||||
$all_participation = $data['all_participation'];
|
||||
$scroll_up_participant = $data['scroll_up_participant'];
|
||||
$scroll_down_participant = $data['scroll_down_participant'];
|
||||
} else {
|
||||
$data = $this->loadDefaultParticipation($too_many);
|
||||
$all_participation = $data['all_participation'];
|
||||
$scroll_down_participant = $data['scroll_down_participant'];
|
||||
$menu_participation = $this->getEmptyParticipant()
|
||||
->setConpherencePHID($conpherence->getPHID())
|
||||
->setParticipantPHID($user->getPHID());
|
||||
$all_participation =
|
||||
array($conpherence->getPHID() => $menu_participation) +
|
||||
$all_participation;
|
||||
}
|
||||
break;
|
||||
case self::PAGING_MODE:
|
||||
$direction = $request->getStr('direction');
|
||||
|
@ -108,16 +120,9 @@ final class ConpherenceListController extends ConpherenceController {
|
|||
break;
|
||||
case self::UNSELECTED_MODE:
|
||||
default:
|
||||
$too_many = ConpherenceParticipantQuery::LIMIT + 1;
|
||||
$all_participation = id(new ConpherenceParticipantQuery())
|
||||
->withParticipantPHIDs(array($user->getPHID()))
|
||||
->setLimit($too_many)
|
||||
->execute();
|
||||
if (count($all_participation) == $too_many) {
|
||||
$node = end($all_participation);
|
||||
unset($all_participation[$node->getConpherencePHID()]);
|
||||
$scroll_down_participant = $node;
|
||||
}
|
||||
$data = $this->loadDefaultParticipation($too_many);
|
||||
$all_participation = $data['all_participation'];
|
||||
$scroll_down_participant = $data['scroll_down_participant'];
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -171,6 +176,26 @@ final class ConpherenceListController extends ConpherenceController {
|
|||
|
||||
}
|
||||
|
||||
private function loadDefaultParticipation($too_many) {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$scroll_down_participant = $this->getEmptyParticipant();
|
||||
|
||||
$all_participation = id(new ConpherenceParticipantQuery())
|
||||
->withParticipantPHIDs(array($viewer->getPHID()))
|
||||
->setLimit($too_many)
|
||||
->execute();
|
||||
if (count($all_participation) == $too_many) {
|
||||
$node = end($all_participation);
|
||||
unset($all_participation[$node->getConpherencePHID()]);
|
||||
$scroll_down_participant = $node;
|
||||
}
|
||||
|
||||
return array(
|
||||
'all_participation' => $all_participation,
|
||||
'scroll_down_participant' => $scroll_down_participant,);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the curious case when we are visiting a conpherence directly
|
||||
* by issuing two separate queries. Otherwise, additional conpherences
|
||||
|
@ -224,7 +249,7 @@ final class ConpherenceListController extends ConpherenceController {
|
|||
return array(
|
||||
'scroll_up_participant' => $scroll_up_participant,
|
||||
'scroll_down_participant' => $scroll_down_participant,
|
||||
'participation' => $participation,
|
||||
'all_participation' => $participation,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,28 @@ final class ConpherenceUpdateController
|
|||
$draft->setDraft($request->getStr('text'));
|
||||
$draft->replaceOrDelete();
|
||||
return new AphrontAjaxResponse();
|
||||
case ConpherenceUpdateActions::JOIN_ROOM:
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$user,
|
||||
$conpherence,
|
||||
PhabricatorPolicyCapability::CAN_JOIN);
|
||||
$xactions[] = id(new ConpherenceTransaction())
|
||||
->setTransactionType(
|
||||
ConpherenceTransactionType::TYPE_PARTICIPANTS)
|
||||
->setNewValue(array('+' => array($user->getPHID())));
|
||||
$delete_draft = true;
|
||||
$message = $request->getStr('text');
|
||||
if ($message) {
|
||||
$message_xactions = $editor->generateTransactionsFromText(
|
||||
$user,
|
||||
$conpherence,
|
||||
$message);
|
||||
$xactions = array_merge($xactions, $message_xactions);
|
||||
}
|
||||
// for now, just redirect back to the conpherence so everything
|
||||
// will work okay...!
|
||||
$response_mode = 'redirect';
|
||||
break;
|
||||
case ConpherenceUpdateActions::MESSAGE:
|
||||
$message = $request->getStr('text');
|
||||
$xactions = $editor->generateTransactionsFromText(
|
||||
|
@ -86,7 +108,10 @@ final class ConpherenceUpdateController
|
|||
break;
|
||||
case ConpherenceUpdateActions::NOTIFICATIONS:
|
||||
$notifications = $request->getStr('notifications');
|
||||
$participant = $conpherence->getParticipant($user->getPHID());
|
||||
$participant = $conpherence->getParticipantIfExists($user->getPHID());
|
||||
if (!$participant) {
|
||||
return id(new Aphront404Response());
|
||||
}
|
||||
$participant->setSettings(array('notifications' => $notifications));
|
||||
$participant->save();
|
||||
$result = pht(
|
||||
|
@ -126,23 +151,23 @@ final class ConpherenceUpdateController
|
|||
break;
|
||||
}
|
||||
|
||||
if ($xactions || ($action == ConpherenceUpdateActions::LOAD)) {
|
||||
if ($xactions) {
|
||||
try {
|
||||
$xactions = $editor->applyTransactions($conpherence, $xactions);
|
||||
if ($delete_draft) {
|
||||
$draft = PhabricatorDraft::newFromUserAndKey(
|
||||
$user,
|
||||
$conpherence->getPHID());
|
||||
$draft->delete();
|
||||
}
|
||||
} catch (PhabricatorApplicationTransactionNoEffectException $ex) {
|
||||
return id(new PhabricatorApplicationTransactionNoEffectResponse())
|
||||
->setCancelURI($this->getApplicationURI($conpherence_id.'/'))
|
||||
->setException($ex);
|
||||
if ($xactions) {
|
||||
try {
|
||||
$xactions = $editor->applyTransactions($conpherence, $xactions);
|
||||
if ($delete_draft) {
|
||||
$draft = PhabricatorDraft::newFromUserAndKey(
|
||||
$user,
|
||||
$conpherence->getPHID());
|
||||
$draft->delete();
|
||||
}
|
||||
} catch (PhabricatorApplicationTransactionNoEffectException $ex) {
|
||||
return id(new PhabricatorApplicationTransactionNoEffectResponse())
|
||||
->setCancelURI($this->getApplicationURI($conpherence_id.'/'))
|
||||
->setException($ex);
|
||||
}
|
||||
}
|
||||
|
||||
if ($xactions || ($action == ConpherenceUpdateActions::LOAD)) {
|
||||
switch ($response_mode) {
|
||||
case 'ajax':
|
||||
$latest_transaction_id = $request->getInt('latest_transaction_id');
|
||||
|
|
|
@ -27,12 +27,14 @@ final class ConpherenceViewController extends
|
|||
}
|
||||
$this->setConpherence($conpherence);
|
||||
|
||||
$participant = $conpherence->getParticipant($user->getPHID());
|
||||
$transactions = $conpherence->getTransactions();
|
||||
$latest_transaction = head($transactions);
|
||||
$write_guard = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
$participant->markUpToDate($conpherence, $latest_transaction);
|
||||
unset($write_guard);
|
||||
$participant = $conpherence->getParticipantIfExists($user->getPHID());
|
||||
if ($participant) {
|
||||
$write_guard = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
$participant->markUpToDate($conpherence, $latest_transaction);
|
||||
unset($write_guard);
|
||||
}
|
||||
|
||||
$data = ConpherenceTransactionView::renderTransactions(
|
||||
$user,
|
||||
|
@ -85,9 +87,24 @@ final class ConpherenceViewController extends
|
|||
|
||||
$conpherence = $this->getConpherence();
|
||||
$user = $this->getRequest()->getUser();
|
||||
$can_join = PhabricatorPolicyFilter::hasCapability(
|
||||
$user,
|
||||
$conpherence,
|
||||
PhabricatorPolicyCapability::CAN_JOIN);
|
||||
$participating = $conpherence->getParticipantIfExists($user->getPHID());
|
||||
if (!$can_join && !$participating) {
|
||||
return null;
|
||||
}
|
||||
$draft = PhabricatorDraft::newFromUserAndKey(
|
||||
$user,
|
||||
$conpherence->getPHID());
|
||||
if ($participating) {
|
||||
$action = ConpherenceUpdateActions::MESSAGE;
|
||||
$button_text = pht('Send');
|
||||
} else {
|
||||
$action = ConpherenceUpdateActions::JOIN_ROOM;
|
||||
$button_text = pht('Join');
|
||||
}
|
||||
$update_uri = $this->getApplicationURI('update/'.$conpherence->getID().'/');
|
||||
|
||||
$this->initBehavior('conpherence-pontificate');
|
||||
|
@ -98,7 +115,7 @@ final class ConpherenceViewController extends
|
|||
->addSigil('conpherence-pontificate')
|
||||
->setWorkflow(true)
|
||||
->setUser($user)
|
||||
->addHiddenInput('action', 'message')
|
||||
->addHiddenInput('action', $action)
|
||||
->appendChild(
|
||||
id(new PhabricatorRemarkupControl())
|
||||
->setUser($user)
|
||||
|
@ -106,7 +123,7 @@ final class ConpherenceViewController extends
|
|||
->setValue($draft->getDraft()))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Send')))
|
||||
->setValue($button_text))
|
||||
->render();
|
||||
|
||||
return $form;
|
||||
|
|
|
@ -130,8 +130,24 @@ final class ConpherenceWidgetController extends ConpherenceController {
|
|||
private function renderSettingsWidgetPaneContent() {
|
||||
$viewer = $this->getViewer();
|
||||
$conpherence = $this->getConpherence();
|
||||
$participants = $conpherence->getParticipants();
|
||||
$participant = $participants[$viewer->getPHID()];
|
||||
$participant = $conpherence->getParticipantIfExists($viewer->getPHID());
|
||||
if (!$participant) {
|
||||
$can_join = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$conpherence,
|
||||
PhabricatorPolicyCapability::CAN_JOIN);
|
||||
if ($can_join) {
|
||||
$text = pht('Settings are available after joining the room.');
|
||||
} else {
|
||||
$text = pht('Settings not applicable to rooms you can not join.');
|
||||
}
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'no-settings',
|
||||
),
|
||||
$text);
|
||||
}
|
||||
$default = ConpherenceSettings::EMAIL_ALWAYS;
|
||||
$preference = $this->getUserPreferences();
|
||||
if ($preference) {
|
||||
|
|
|
@ -321,6 +321,15 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
|||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
||||
$message_count = 0;
|
||||
foreach ($xactions as $xaction) {
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case PhabricatorTransactions::TYPE_COMMENT:
|
||||
$message_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update everyone's participation status on the last xaction -only-
|
||||
$xaction = end($xactions);
|
||||
$xaction_phid = $xaction->getPHID();
|
||||
|
@ -333,8 +342,8 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
|||
if ($phid != $user->getPHID()) {
|
||||
if ($participant->getParticipationStatus() != $behind) {
|
||||
$participant->setBehindTransactionPHID($xaction_phid);
|
||||
// decrement one as this is the message putting them behind!
|
||||
$participant->setSeenMessageCount($object->getMessageCount() - 1);
|
||||
$participant->setSeenMessageCount(
|
||||
$object->getMessageCount() - $message_count);
|
||||
}
|
||||
$participant->setParticipationStatus($behind);
|
||||
$participant->setDateTouched($time);
|
||||
|
|
|
@ -98,9 +98,9 @@ final class ConpherenceThread extends ConpherenceDAO
|
|||
$participants = $this->getParticipants();
|
||||
return $participants[$phid];
|
||||
}
|
||||
public function getParticipantIfExists($phid) {
|
||||
public function getParticipantIfExists($phid, $default = null) {
|
||||
$participants = $this->getParticipants();
|
||||
return idx($participants, $phid);
|
||||
return idx($participants, $phid, $default);
|
||||
}
|
||||
|
||||
public function getParticipantPHIDs() {
|
||||
|
@ -221,7 +221,10 @@ final class ConpherenceThread extends ConpherenceDAO
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
|
||||
|
||||
|
||||
public function getCapabilities() {
|
||||
return array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
|
|
|
@ -393,6 +393,10 @@ abstract class PhabricatorApplicationTransactionEditor
|
|||
case PhabricatorTransactions::TYPE_EDIT_POLICY:
|
||||
$object->setEditPolicy($xaction->getNewValue());
|
||||
break;
|
||||
case PhabricatorTransactions::TYPE_JOIN_POLICY:
|
||||
$object->setJoinPolicy($xaction->getNewValue());
|
||||
break;
|
||||
|
||||
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
||||
$field = $this->getCustomFieldForTransaction($object, $xaction);
|
||||
return $field->applyApplicationTransactionInternalEffects($xaction);
|
||||
|
|
|
@ -376,3 +376,15 @@
|
|||
.conpherence-widget-pane .notifications-update {
|
||||
margin: 3px 0px 0px 4px;
|
||||
}
|
||||
|
||||
.conpherence-widget-pane .no-settings {
|
||||
width: 200px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: {$greytext};
|
||||
}
|
||||
|
||||
.device .conpherence-widget-pane .no-settings {
|
||||
width: 60px;
|
||||
margin: 0 auto 0 auto;
|
||||
}
|
||||
|
|
|
@ -321,13 +321,17 @@ JX.behavior('conpherence-menu', function(config) {
|
|||
function _focusTextarea() {
|
||||
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
|
||||
var form_root = JX.DOM.find(root, 'div', 'conpherence-form');
|
||||
var textarea = JX.DOM.find(form_root, 'textarea');
|
||||
// We may have a draft so do this JS trick so we end up focused at the
|
||||
// end of the draft.
|
||||
var textarea_value = textarea.value;
|
||||
textarea.value = '';
|
||||
JX.DOM.focus(textarea);
|
||||
textarea.value = textarea_value;
|
||||
try {
|
||||
var textarea = JX.DOM.find(form_root, 'textarea');
|
||||
// We may have a draft so do this JS trick so we end up focused at the
|
||||
// end of the draft.
|
||||
var textarea_value = textarea.value;
|
||||
textarea.value = '';
|
||||
JX.DOM.focus(textarea);
|
||||
textarea.value = textarea_value;
|
||||
} catch (ex) {
|
||||
// no textarea? no problem
|
||||
}
|
||||
}
|
||||
JX.Stratcom.listen(
|
||||
'conpherence-redraw-thread',
|
||||
|
|
Loading…
Reference in a new issue