Added browsing settings

This commit is contained in:
Marcin Kurczewski 2014-09-07 14:50:16 +02:00
parent f5606c4169
commit e6b37d8e57
12 changed files with 150 additions and 20 deletions

View file

@ -34,6 +34,7 @@
<script type="text/javascript" src="/js/Api.js"></script> <script type="text/javascript" src="/js/Api.js"></script>
<script type="text/javascript" src="/js/Auth.js"></script> <script type="text/javascript" src="/js/Auth.js"></script>
<script type="text/javascript" src="/js/Util.js"></script> <script type="text/javascript" src="/js/Util.js"></script>
<script type="text/javascript" src="/js/BrowsingSettings.js"></script>
<script type="text/javascript" src="/js/Controls/FileDropper.js"></script> <script type="text/javascript" src="/js/Controls/FileDropper.js"></script>
<script type="text/javascript" src="/js/Presenters/TopNavigationPresenter.js"></script> <script type="text/javascript" src="/js/Presenters/TopNavigationPresenter.js"></script>
<script type="text/javascript" src="/js/Presenters/PagedCollectionPresenter.js"></script> <script type="text/javascript" src="/js/Presenters/PagedCollectionPresenter.js"></script>

View file

@ -0,0 +1,86 @@
var App = App || {};
App.BrowsingSettings = function(
promise,
auth,
api) {
var settings = getDefaultSettings();
auth.startObservingLoginChanges('top-navigation', loginStateChanged);
readFromLocalStorage();
if (auth.isLoggedIn())
loginStateChanged();
function setSettings(newSettings) {
settings = newSettings;
return save();
}
function getSettings() {
return settings;
}
function getDefaultSettings() {
return {
hideDownvoted: true,
endlessScroll: true,
listPosts: {
safe: true,
sketchy: true,
unsafe: true,
},
};
}
function loginStateChanged() {
readFromUser(auth.getCurrentUser());
}
function readFromLocalStorage() {
readFromString(localStorage.getItem('browsingSettings'));
}
function readFromUser(user) {
readFromString(user.browsingSettings);
}
function readFromString(string) {
if (!string)
return;
try {
settings = JSON.parse(string);
} catch (e) {
}
}
function saveToLocalStorage() {
localStorage.setItem('browsingSettings', JSON.stringify(settings));
}
function saveToUser(user) {
var formData = {
browsingSettings: JSON.stringify(settings),
};
return api.put('/users/' + user.name, formData);
}
function save() {
return promise.make(function(resolve, reject) {
saveToLocalStorage();
if (auth.isLoggedIn()) {
saveToUser(auth.getCurrentUser()).then(resolve).fail(reject);
} else {
resolve();
}
});
}
return {
getSettings: getSettings,
setSettings: setSettings,
};
}
App.DI.registerSingleton('browsingSettings', App.BrowsingSettings);

View file

@ -5,7 +5,9 @@ App.Presenters.UserBrowsingSettingsPresenter = function(
jQuery, jQuery,
util, util,
promise, promise,
auth) { auth,
browsingSettings,
messagePresenter) {
var target; var target;
var template; var template;
@ -29,7 +31,27 @@ App.Presenters.UserBrowsingSettingsPresenter = function(
function render() { function render() {
var $el = jQuery(target); var $el = jQuery(target);
$el.html(template({user: user})); $el.html(template({user: user, settings: browsingSettings.getSettings()}));
$el.find('form').submit(browsingSettingsFormSubmitted);
}
function browsingSettingsFormSubmitted(e) {
e.preventDefault();
var $el = jQuery(target);
var $messages = $el.find('.messages');
messagePresenter.hideMessages($messages);
var newSettings = {
endlessScroll: $el.find('[name=endless-scroll]:visible').prop('checked'),
hideDownvoted: $el.find('[name=hide-downvoted]:visible').prop('checked'),
listPosts: {
safe: $el.find('[name=listSafePosts]:visible').prop('checked'),
sketchy: $el.find('[name=listSketchyPosts]:visible').prop('checked'),
unsafe: $el.find('[name=listUnsafePosts]:visible').prop('checked'),
},
};
browsingSettings.setSettings(newSettings).then(function() {
messagePresenter.showInfo($messages, 'Browsing settings updated!');
});
} }
function getPrivileges() { function getPrivileges() {

View file

@ -4,9 +4,8 @@
<div class="form-row"> <div class="form-row">
<label class="form-label" for="account-removal-confirmation">Confirmation:</label> <label class="form-label" for="account-removal-confirmation">Confirmation:</label>
<div class="form-input"> <div class="form-input">
<input type="hidden" name="confirmation" value="0"/>
<label for="account-removal-confirmation"> <label for="account-removal-confirmation">
<input type="checkbox" id="account-removal-confirmation" name="confirmation" value="1"/> <input type="checkbox" id="account-removal-confirmation" name="confirmation"/>
I confirm that I want to delete this account. I confirm that I want to delete this account.
</label> </label>
</div> </div>

View file

@ -4,43 +4,38 @@
<div class="form-row"> <div class="form-row">
<label class="form-label">Safety:</label> <label class="form-label">Safety:</label>
<div class="form-input"> <div class="form-input">
<input type="hidden" name="safety[]" value=""/>
<label for="browsing-settings-safety-safe"> <label for="browsing-settings-safety-safe">
<input type="checkbox" id="browsing-settings-safety-safe" name="safety[]" value="1"/> <input <% print(settings.listPosts.safe ? 'checked="checked"' : '') %> type="checkbox" id="browsing-settings-safety-safe" name="listSafePosts" value="1"/>
Safe Safe
</label> </label>
<input type="hidden" name="safety[]" value=""/>
<label for="browsing-settings-safety-sketchy"> <label for="browsing-settings-safety-sketchy">
<input type="checkbox" id="browsing-settings-safety-sketchy" name="safety[]" value="2"/> <input <% print(settings.listPosts.sketchy ? 'checked="checked"' : '') %> type="checkbox" id="browsing-settings-safety-sketchy" name="listSketchyPosts" value="2"/>
Sketchy Sketchy
</label> </label>
<input type="hidden" name="safety[]" value=""/>
<label for="browsing-settings-safety-unsafe"> <label for="browsing-settings-safety-unsafe">
<input type="checkbox" id="browsing-settings-safety-unsafe" name="safety[]" value="3"/> <input <% print(settings.listPosts.unsafe ? 'checked="checked"' : '') %> type="checkbox" id="browsing-settings-safety-unsafe" name="listUnsafePosts" value="3"/>
Unsafe Unsafe
</label> </label>
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<label class="form-label" for="browsing-settings-endless-scrolling">Endless scrolling:</label> <label class="form-label" for="browsing-settings-endless-scroll">Endless scroll:</label>
<div class="form-input"> <div class="form-input">
<input type="hidden" name="endless-scrolling" value="0"/> <label for="browsing-settings-endless-scroll">
<label for="browsing-settings-endless-scrolling"> <input <% print(settings.endlessScroll ? 'checked="checked"' : '') %> type="checkbox" id="browsing-settings-endless-scroll" name="endless-scroll" value="1"/>
<input type="checkbox" id="browsing-settings-endless-scrolling" name="endless-scrolling" value="1"/>
Enabled Enabled
</label> </label>
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<label class="form-label" for="browsing-settings-hide-disliked-posts">Hide down-voted:</label> <label class="form-label" for="browsing-settings-hide-downvoted">Hide down-voted:</label>
<div class="form-input"> <div class="form-input">
<input type="hidden" name="hide-disliked-posts" value="0"/> <label for="browsing-settings-hide-downvoted">
<label for="browsing-settings-hide-disliked-posts"> <input <% print(settings.hideDownvoted ? 'checked="checked"' : '') %>type="checkbox" id="browsing-settings-hide-downvoted" name="hide-downvoted" value="1"/>
<input type="checkbox" id="browsing-settings-hide-disliked-posts" name="hide-disliked-posts" value="1"/>
Enabled Enabled
</label> </label>
</div> </div>

View file

@ -26,9 +26,8 @@
<div class="form-input"> <div class="form-input">
<button type="submit">Log in</button> <button type="submit">Log in</button>
&nbsp; &nbsp;
<input type="hidden" name="remember" value="0"/>
<label> <label>
<input type="checkbox" name="remember" value="1"/> <input type="checkbox" name="remember"/>
Remember me Remember me
</label> </label>
</div> </div>

View file

@ -99,6 +99,11 @@ final class UserController extends AbstractController
$this->privilegeService->assertPrivilege(\Szurubooru\Privilege::CHANGE_ACCESS_RANK); $this->privilegeService->assertPrivilege(\Szurubooru\Privilege::CHANGE_ACCESS_RANK);
} }
if ($formData->browsingSettings)
{
$this->privilegeService->assertLoggedIn($userName);
}
$user = $this->userService->updateUser($userName, $formData); $user = $this->userService->updateUser($userName, $formData);
return $this->userViewProxy->fromEntity($user); return $this->userViewProxy->fromEntity($user);
} }

View file

@ -22,6 +22,11 @@ class UserViewProxy extends AbstractViewProxy
$result->lastLoginTime = $user->lastLoginTime; $result->lastLoginTime = $user->lastLoginTime;
$result->avatarStyle = $user->avatarStyle; $result->avatarStyle = $user->avatarStyle;
if ($this->privilegeService->isLoggedIn($user))
{
$result->browsingSettings = $user->browsingSettings;
}
if ($this->privilegeService->hasPrivilege(\Szurubooru\Privilege::VIEW_ALL_EMAIL_ADDRESSES) or if ($this->privilegeService->hasPrivilege(\Szurubooru\Privilege::VIEW_ALL_EMAIL_ADDRESSES) or
$this->privilegeService->isLoggedIn($user)) $this->privilegeService->isLoggedIn($user))
{ {

View file

@ -21,4 +21,5 @@ final class User extends Entity
public $registrationTime; public $registrationTime;
public $lastLoginTime; public $lastLoginTime;
public $avatarStyle; public $avatarStyle;
public $browsingSettings;
} }

View file

@ -8,6 +8,7 @@ class UserEditFormData
public $accessRank; public $accessRank;
public $password; public $password;
public $avatarStyle; public $avatarStyle;
public $browsingSettings;
public function __construct($inputReader = null) public function __construct($inputReader = null)
{ {
@ -19,6 +20,7 @@ class UserEditFormData
$this->accessRank = $inputReader->accessRank; $this->accessRank = $inputReader->accessRank;
$this->avatarStyle = $inputReader->avatarStyle; $this->avatarStyle = $inputReader->avatarStyle;
$this->avatarContent = $inputReader->avatarContent; $this->avatarContent = $inputReader->avatarContent;
$this->browsingSettings = $inputReader->browsingSettings;
} }
} }
} }

View file

@ -47,6 +47,12 @@ class PrivilegeService
throw new \DomainException('Unprivileged operation'); throw new \DomainException('Unprivileged operation');
} }
public function assertLoggedIn($userIdentifier)
{
if (!$this->isLoggedIn($userIdentifier))
throw new \DomainException('Unprivileged operation');
}
public function isLoggedIn($userIdentifier) public function isLoggedIn($userIdentifier)
{ {
$loggedInUser = $this->authService->getLoggedInUser(); $loggedInUser = $this->authService->getLoggedInUser();

View file

@ -109,6 +109,15 @@ class UserService
$user->accessRank = \Szurubooru\Helpers\EnumHelper::accessRankFromString($formData->accessRank); $user->accessRank = \Szurubooru\Helpers\EnumHelper::accessRankFromString($formData->accessRank);
} }
if ($formData->browsingSettings !== null)
{
if (!is_string($formData->browsingSettings))
throw new \InvalidArgumentException('Browsing settings must be stringified JSON.');
if (strlen($formData->browsingSettings) > 2000)
throw new \InvalidArgumentException('Stringified browsing settings can have at most 2000 characters.');
$user->browsingSettings = $formData->browsingSettings;
}
if ($formData->email !== null) if ($formData->email !== null)
$this->sendActivationMailIfNeeded($user); $this->sendActivationMailIfNeeded($user);