Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Conpherence - add per thread notification setting

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...
commit 23dc68604561e87738b98b1ee4a55166f886692d 1 parent 8a0fccf
@bobtrahan bobtrahan authored
View
2  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;
View
9 src/__celerity_resource_map__.php
@@ -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(
@@ -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(
@@ -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',
),
View
4 src/__phutil_library_map__.php
@@ -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',
@@ -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',
@@ -1907,6 +1909,7 @@
'ConpherencePeopleMenuEventListener' => 'PhutilEventListener',
'ConpherencePontificateControl' => 'AphrontFormControl',
'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler',
+ 'ConpherenceSettings' => 'ConpherenceConstants',
'ConpherenceThread' =>
array(
0 => 'ConpherenceDAO',
@@ -2907,6 +2910,7 @@
'PhabricatorSettingsMainController' => 'PhabricatorController',
'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel',
+ 'PhabricatorSettingsPanelConpherencePreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelDiffPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelDisplayPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelEmailAddresses' => 'PhabricatorSettingsPanel',
View
22 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;
+ }
+}
View
11 src/applications/conpherence/controller/ConpherenceUpdateController.php
@@ -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');
View
71 src/applications/conpherence/controller/ConpherenceWidgetController.php
@@ -8,6 +8,15 @@
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;
@@ -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);
@@ -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,
@@ -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() {
View
30 src/applications/conpherence/editor/ConpherenceEditor.php
@@ -159,13 +159,15 @@ 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)
@@ -173,6 +175,8 @@ protected function applyCustomExternalTransaction(
->setBehindTransactionPHID($xaction->getPHID())
->save();
}
+ $participants = mpull($participants, null, 'getParticipantPHID');
+ $object->attachParticipants($participants);
break;
}
}
@@ -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) {
@@ -251,5 +276,4 @@ protected function supportsFeed() {
protected function supportsSearch() {
return false;
}
-
}
View
13 src/applications/conpherence/storage/ConpherenceParticipant.php
@@ -10,6 +10,19 @@
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()) {
View
84 src/applications/settings/panel/PhabricatorSettingsPanelConpherencePreferences.php
@@ -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,
+ );
+ }
+}
+
View
2  src/applications/settings/storage/PhabricatorUserPreferences.php
@@ -25,6 +25,8 @@
const PREFERENCE_DIFF_FILETREE = 'diff-filetree';
+ const PREFERENCE_CONPH_NOTIFICATIONS = 'conph-notifications';
+
protected $userPHID;
protected $preferences = array();
View
6 src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -1180,7 +1180,11 @@ public function getPatches() {
'20130319.phabricatorfileexplicitupload.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath(
- '20130319.phabricatorfileexplicitupload.sql'),
+ '20130319.phabricatorfileexplicitupload.sql')
+ ),
+ '20130319.conpherence.sql' => array(
+ 'type' => 'sql',
+ 'name' => $this->getPatchPath('20130319.conpherence.sql'),
),
'20130320.phlux.sql' => array(
'type' => 'sql',
View
10 webroot/rsrc/css/application/conpherence/widget-pane.css
@@ -26,6 +26,11 @@
width: 100%;
}
+.conpherence-widget-pane .aphront-form-inset {
+ border: 0;
+ background: url('/rsrc/image/texture/dust_background.jpg');
+}
+
.conpherence-widget-pane .widgets-header {
background-color: #d8dce2;
box-shadow: 0px 2px 2px rgba(0,0,0,0.15);
@@ -186,3 +191,8 @@
.conpherence-widget-pane .phabricator-remarkup-embed-layout-link {
padding-bottom: 1px;
}
+
+/* settings widget */
+.conpherence-widget-pane .notifications-update {
+ margin: 2px 0px 0px 8px;
+}
View
7 webroot/rsrc/js/application/conpherence/behavior-pontificate.js
@@ -52,13 +52,6 @@ JX.behavior('conpherence-pontificate', function(config) {
JX.DOM.listen(
root,
- ['submit', 'didSyntheticSubmit'],
- null,
- onsubmit
- );
-
- JX.DOM.listen(
- root,
['click'],
'conpherence-pontificate',
onsubmit
View
30 webroot/rsrc/js/application/conpherence/behavior-widget-pane.js
@@ -1,8 +1,11 @@
/**
- * @provides javelin-behavior-conpherence-widget-pane
* @requires javelin-behavior
* javelin-dom
* javelin-stratcom
+ * javelin-workflow
+ * javelin-util
+ * phabricator-notification
+ * @provides javelin-behavior-conpherence-widget-pane
*/
JX.behavior('conpherence-widget-pane', function(config) {
@@ -36,4 +39,29 @@ JX.behavior('conpherence-widget-pane', function(config) {
}
);
+ var settingsRoot = JX.$(config.settings_widget);
+
+ var onsubmitSettings = function (e) {
+ e.kill();
+ var form = JX.DOM.find(settingsRoot, 'form');
+ var button = JX.DOM.find(form, 'button');
+ JX.Workflow.newFromForm(form)
+ .setHandler(JX.bind(this, function (r) {
+ new JX.Notification()
+ .setDuration(6000)
+ .setContent(r)
+ .show();
+ button.disabled = '';
+ JX.DOM.alterClass(button, 'disabled', false);
+ }))
+ .start();
+ };
+
+ JX.DOM.listen(
+ settingsRoot,
+ ['click'],
+ 'notifications-update',
+ onsubmitSettings
+ );
+
});
Please sign in to comment.
Something went wrong with that request. Please try again.