Skip to content

Commit

Permalink
Conpherence - add per thread notification setting
Browse files Browse the repository at this point in the history
Summary: Introduces a new settings panel for Conpherence specific settings.

Test Plan:
started a thread with a test user, thus two participants total. Replied to conpherence, toggling notification settings in between. Verified 1 or 2 emails were sent as appropos to the current toggle.

Toggled global setting and verified setting was updated in conpherences where nothing was specified. Verified setting conpherence setting overrides global setting.

Reviewers: epriestley, chad

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2521

Differential Revision: https://secure.phabricator.com/D5391
  • Loading branch information
bobtrahan committed Mar 26, 2013
1 parent 8a0fccf commit 23dc686
Show file tree
Hide file tree
Showing 14 changed files with 284 additions and 17 deletions.
2 changes: 2 additions & 0 deletions resources/sql/patches/20130319.conpherence.sql
@@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_conpherence.conpherence_participant
ADD settings LONGTEXT NOT NULL COLLATE utf8_bin AFTER behindTransactionPHID;
9 changes: 6 additions & 3 deletions src/__celerity_resource_map__.php
Expand Up @@ -840,7 +840,7 @@
),
'conpherence-widget-pane-css' =>
array(
'uri' => '/res/0e4a8ded/rsrc/css/application/conpherence/widget-pane.css',
'uri' => '/res/bd8ca250/rsrc/css/application/conpherence/widget-pane.css',
'type' => 'css',
'requires' =>
array(
Expand Down Expand Up @@ -1206,7 +1206,7 @@
),
'javelin-behavior-conpherence-pontificate' =>
array(
'uri' => '/res/15263692/rsrc/js/application/conpherence/behavior-pontificate.js',
'uri' => '/res/fe634761/rsrc/js/application/conpherence/behavior-pontificate.js',
'type' => 'js',
'requires' =>
array(
Expand All @@ -1219,13 +1219,16 @@
),
'javelin-behavior-conpherence-widget-pane' =>
array(
'uri' => '/res/43a0fe1b/rsrc/js/application/conpherence/behavior-widget-pane.js',
'uri' => '/res/52b80633/rsrc/js/application/conpherence/behavior-widget-pane.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
4 => 'javelin-util',
5 => 'phabricator-notification',
),
'disk' => '/rsrc/js/application/conpherence/behavior-widget-pane.js',
),
Expand Down
4 changes: 4 additions & 0 deletions src/__phutil_library_map__.php
Expand Up @@ -240,6 +240,7 @@
'ConpherencePeopleMenuEventListener' => 'applications/conpherence/events/ConpherencePeopleMenuEventListener.php',
'ConpherencePontificateControl' => 'applications/conpherence/view/ConpherencePontificateControl.php',
'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php',
'ConpherenceSettings' => 'applications/conpherence/constants/ConpherenceSettings.php',
'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php',
'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
Expand Down Expand Up @@ -1301,6 +1302,7 @@
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
'PhabricatorSettingsPanelAccount' => 'applications/settings/panel/PhabricatorSettingsPanelAccount.php',
'PhabricatorSettingsPanelConduit' => 'applications/settings/panel/PhabricatorSettingsPanelConduit.php',
'PhabricatorSettingsPanelConpherencePreferences' => 'applications/settings/panel/PhabricatorSettingsPanelConpherencePreferences.php',
'PhabricatorSettingsPanelDiffPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php',
'PhabricatorSettingsPanelDisplayPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php',
'PhabricatorSettingsPanelEmailAddresses' => 'applications/settings/panel/PhabricatorSettingsPanelEmailAddresses.php',
Expand Down Expand Up @@ -1907,6 +1909,7 @@
'ConpherencePeopleMenuEventListener' => 'PhutilEventListener',
'ConpherencePontificateControl' => 'AphrontFormControl',
'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler',
'ConpherenceSettings' => 'ConpherenceConstants',
'ConpherenceThread' =>
array(
0 => 'ConpherenceDAO',
Expand Down Expand Up @@ -2907,6 +2910,7 @@
'PhabricatorSettingsMainController' => 'PhabricatorController',
'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelConpherencePreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelDiffPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelDisplayPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelEmailAddresses' => 'PhabricatorSettingsPanel',
Expand Down
22 changes: 22 additions & 0 deletions src/applications/conpherence/constants/ConpherenceSettings.php
@@ -0,0 +1,22 @@
<?php

final class ConpherenceSettings extends ConpherenceConstants {

const EMAIL_ALWAYS = 0;
const NOTIFICATIONS_ONLY = 1;

public static function getHumanString($constant) {
$string = pht('Unknown setting.');

switch ($constant) {
case self::EMAIL_ALWAYS:
$string = pht('Email me every update.');
break;
case self::NOTIFICATIONS_ONLY:
$string = pht('Notifications only.');
break;
}

return $string;
}
}
Expand Up @@ -60,6 +60,17 @@ public function processRequest() {
$conpherence,
$message);
break;
case 'notifications':
$notifications = $request->getStr('notifications');
$participant = $conpherence->getParticipant($user->getPHID());
$participant->setSettings(array('notifications' => $notifications));
$participant->save();
$result = pht(
'Updated notification settings to "%s".',
ConpherenceSettings::getHumanString($notifications));
return id(new AphrontAjaxResponse())
->setContent($result);
break;
case 'metadata':
$xactions = array();
$top = $request->getInt('image_y');
Expand Down
Expand Up @@ -8,6 +8,15 @@ final class ConpherenceWidgetController extends

private $conpherenceID;
private $conpherence;
private $userPreferences;

public function setUserPreferences(PhabricatorUserPreferences $pref) {
$this->userPreferences = $pref;
return $this;
}
public function getUserPreferences() {
return $this->userPreferences;
}

public function setConpherence(ConpherenceThread $conpherence) {
$this->conpherence = $conpherence;
Expand Down Expand Up @@ -44,6 +53,8 @@ public function processRequest() {
->executeOne();
$this->setConpherence($conpherence);

$this->setUserPreferences($user->loadPreferences());

$widgets = $this->renderWidgetPaneContent();
$content = $widgets;
return id(new AphrontAjaxResponse())->setContent($content);
Expand All @@ -57,8 +68,8 @@ private function renderWidgetPaneContent() {
Javelin::initBehavior(
'conpherence-widget-pane',
array(
'form_pane' => 'conpherence-form',
'file_widget' => 'widgets-files',
'settings_widget' => 'widgets-settings',
'widgetRegistery' => array(
'widgets-conpherence-list' => $cant_toggle,
'widgets-conversation' => $cant_toggle,
Expand Down Expand Up @@ -201,7 +212,63 @@ private function renderPeopleWidgetPaneContent() {
}

private function renderSettingsWidgetPaneContent() {
return 'TODO - settings';
$user = $this->getRequest()->getUser();
$conpherence = $this->getConpherence();
$participants = $conpherence->getParticipants();
$participant = $participants[$user->getPHID()];
$default = ConpherenceSettings::EMAIL_ALWAYS;
$preference = $this->getUserPreferences();
if ($preference) {
$default = $preference->getPreference(
PhabricatorUserPreferences::PREFERENCE_CONPH_NOTIFICATIONS,
ConpherenceSettings::EMAIL_ALWAYS);
}
$settings = $participant->getSettings();
$notifications = idx(
$settings,
'notifications',
$default);
$options = id(new AphrontFormRadioButtonControl())
->addButton(
ConpherenceSettings::EMAIL_ALWAYS,
ConpherenceSettings::getHumanString(
ConpherenceSettings::EMAIL_ALWAYS),
'')
->addButton(
ConpherenceSettings::NOTIFICATIONS_ONLY,
ConpherenceSettings::getHumanString(
ConpherenceSettings::NOTIFICATIONS_ONLY),
'')
->setName('notifications')
->setValue($notifications);

$href = $this->getApplicationURI(
'update/'.$conpherence->getID().'/');
$layout = array(
$options,
phutil_tag(
'input',
array(
'type' => 'hidden',
'name' => 'action',
'value' => 'notifications'
)),
javelin_tag(
'button',
array(
'sigil' => 'notifications-update',
'class' => 'notifications-update grey',
),
pht('Update Notifications'))
);

return phabricator_form(
$user,
array(
'method' => 'POST',
'action' => $href,
),
$layout);
}

private function renderCalendarWidgetPaneContent() {
Expand Down
30 changes: 27 additions & 3 deletions src/applications/conpherence/editor/ConpherenceEditor.php
Expand Up @@ -159,20 +159,24 @@ protected function applyCustomExternalTransaction(
}
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
$participants = array();
foreach ($xaction->getNewValue() as $participant) {
if ($participant == $this->getActor()->getPHID()) {
$status = ConpherenceParticipationStatus::UP_TO_DATE;
} else {
$status = ConpherenceParticipationStatus::BEHIND;
}
id(new ConpherenceParticipant())
$participants[] =
id(new ConpherenceParticipant())
->setConpherencePHID($object->getPHID())
->setParticipantPHID($participant)
->setParticipationStatus($status)
->setDateTouched(time())
->setBehindTransactionPHID($xaction->getPHID())
->save();
}
$participants = mpull($participants, null, 'getParticipantPHID');
$object->attachParticipants($participants);
break;
}
}
Expand Down Expand Up @@ -221,7 +225,28 @@ protected function buildMailTemplate(PhabricatorLiskDAO $object) {

protected function getMailTo(PhabricatorLiskDAO $object) {
$participants = $object->getParticipants();
return array_keys($participants);
$preferences = id(new PhabricatorUserPreferences())
->loadAllWhere('userPHID in (%Ls)', array_keys($participants));
$preferences = mpull($preferences, null, 'getUserPHID');
$to_phids = array();
foreach ($participants as $phid => $participant) {
$default = ConpherenceSettings::EMAIL_ALWAYS;
$preference = idx($preferences, $phid);
if ($preference) {
$default = $preference->getPreference(
PhabricatorUserPreferences::PREFERENCE_CONPH_NOTIFICATIONS,
ConpherenceSettings::EMAIL_ALWAYS);
}
$settings = $participant->getSettings();
$notifications = idx(
$settings,
'notifications',
$default);
if ($notifications == ConpherenceSettings::EMAIL_ALWAYS) {
$to_phids[] = $phid;
}
}
return $to_phids;
}

protected function getMailCC(PhabricatorLiskDAO $object) {
Expand Down Expand Up @@ -251,5 +276,4 @@ protected function supportsFeed() {
protected function supportsSearch() {
return false;
}

}
13 changes: 13 additions & 0 deletions src/applications/conpherence/storage/ConpherenceParticipant.php
Expand Up @@ -10,6 +10,19 @@ final class ConpherenceParticipant extends ConpherenceDAO {
protected $participationStatus;
protected $behindTransactionPHID;
protected $dateTouched;
protected $settings = array();

public function getConfiguration() {
return array(
self::CONFIG_SERIALIZATION => array(
'settings' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}

public function getSettings() {
return nonempty($this->settings, array());
}

public function markUpToDate(ConpherenceTransaction $xaction) {
if (!$this->isUpToDate()) {
Expand Down
@@ -0,0 +1,84 @@
<?php

final class PhabricatorSettingsPanelConpherencePreferences
extends PhabricatorSettingsPanel {

public function isEnabled() {
// TODO - epriestley - resolve isBeta and isInstalled for
// PhabricatorApplication
$app = PhabricatorApplication::getByClass(
'PhabricatorApplicationConpherence');
$is_prod = !$app->isBeta();
$allow_beta =
PhabricatorEnv::getEnvConfig('phabricator.show-beta-applications');
return ($is_prod || $allow_beta) && $app->isInstalled();
}

public function getPanelKey() {
return 'conpherence';
}

public function getPanelName() {
return pht('Conpherence Preferences');
}

public function getPanelGroup() {
return pht('Application Settings');
}

public function processRequest(AphrontRequest $request) {
$user = $request->getUser();
$preferences = $user->loadPreferences();

$pref = PhabricatorUserPreferences::PREFERENCE_CONPH_NOTIFICATIONS;

if ($request->isFormPost()) {
$notifications = $request->getInt($pref);
$preferences->setPreference($pref, $notifications);
$preferences->save();
return id(new AphrontRedirectResponse())
->setURI($this->getPanelURI('?saved=true'));
}

$form = id(new AphrontFormView())
->setUser($user)
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Conpherence Notifications'))
->setName($pref)
->setValue($preferences->getPreference($pref))
->setOptions(
array(
ConpherenceSettings::EMAIL_ALWAYS
=> pht('Email Always'),
ConpherenceSettings::NOTIFICATIONS_ONLY
=> pht('Notifications Only'),
))
->setCaption(
pht('Should Conpherence send emails for updates or '.
'notifications only? This global setting can be overridden '.
'on a per-thread basis within Conpherence.')))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Save Preferences')));

$panel = new AphrontPanelView();
$panel->setHeader(pht('Conpherence Preferences'));
$panel->appendChild($form);
$panel->setNoBackground();

$error_view = null;
if ($request->getBool('saved')) {
$error_view = id(new AphrontErrorView())
->setTitle(pht('Preferences Saved'))
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
->setErrors(array(pht('Your preferences have been saved.')));
}

return array(
$error_view,
$panel,
);
}
}

Expand Up @@ -25,6 +25,8 @@ final class PhabricatorUserPreferences extends PhabricatorUserDAO {

const PREFERENCE_DIFF_FILETREE = 'diff-filetree';

const PREFERENCE_CONPH_NOTIFICATIONS = 'conph-notifications';

protected $userPHID;
protected $preferences = array();

Expand Down

0 comments on commit 23dc686

Please sign in to comment.