settings page and custom css for users

This commit is contained in:
Athou
2013-04-04 11:36:24 +02:00
parent 19ab1810ce
commit 2f13891f81
17 changed files with 1744 additions and 14 deletions

View File

@@ -258,6 +258,11 @@
<artifactId>mousetrap</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>codemirror</artifactId>
<version>3.11</version>
</dependency>
</dependencies>
<profiles>

View File

@@ -5,6 +5,7 @@ import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@@ -25,6 +26,10 @@ public class UserSettings extends AbstractModel {
@Column(nullable = false)
private ReadingMode readingMode;
@Lob
@Column(length = Integer.MAX_VALUE)
private String customCss;
public ReadingMode getReadingMode() {
return readingMode;
}
@@ -41,4 +46,12 @@ public class UserSettings extends AbstractModel {
this.user = user;
}
public String getCustomCss() {
return customCss;
}
public void setCustomCss(String customCss) {
this.customCss = customCss;
}
}

View File

@@ -6,6 +6,7 @@ import java.io.Serializable;
public class Settings implements Serializable {
private String readingMode;
private String customCss;
public String getReadingMode() {
return readingMode;
@@ -15,4 +16,12 @@ public class Settings implements Serializable {
this.readingMode = readingMode;
}
public String getCustomCss() {
return customCss;
}
public void setCustomCss(String customCss) {
this.customCss = customCss;
}
}

View File

@@ -1,17 +1,24 @@
package com.commafeed.frontend.pages;
import javax.inject.Inject;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import com.commafeed.backend.dao.UserSettingsService;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.model.UserSettings;
import com.commafeed.frontend.CommaFeedSession;
import com.commafeed.frontend.SecurityCheck;
import com.commafeed.frontend.references.UserCustomCssReference;
import com.commafeed.frontend.references.angular.AngularReference;
import com.commafeed.frontend.references.angular.AngularResourceReference;
import com.commafeed.frontend.references.angular.AngularSanitizeReference;
import com.commafeed.frontend.references.angularui.AngularUIReference;
import com.commafeed.frontend.references.angularuibootstrap.AngularUIBootstrapReference;
import com.commafeed.frontend.references.angularuistate.AngularUIStateReference;
import com.commafeed.frontend.references.codemirror.CodeMirrorCssReference;
import com.commafeed.frontend.references.csstreeview.CssTreeViewReference;
import com.commafeed.frontend.references.mousetrap.MouseTrapReference;
import com.commafeed.frontend.references.nggrid.NGGridReference;
@@ -24,6 +31,9 @@ import com.commafeed.frontend.references.spinjs.SpinJSReference;
@SecurityCheck(Role.USER)
public class HomePage extends BasePage {
@Inject
UserSettingsService settingsService;
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
@@ -39,6 +49,7 @@ public class HomePage extends BasePage {
SpinJSReference.renderHead(response);
MouseTrapReference.renderHead(response);
NGGridReference.renderHead(response);
CodeMirrorCssReference.renderHead(response);
CssTreeViewReference.renderHead(response);
@@ -48,5 +59,16 @@ public class HomePage extends BasePage {
response.render(JavaScriptHeaderItem.forUrl("js/services.js"));
response.render(CssHeaderItem.forUrl("css/app.css"));
response.render(CssHeaderItem
.forReference(new UserCustomCssReference() {
@Override
protected String getCss() {
UserSettings settings = settingsService
.findByUser(CommaFeedSession.get().getUser());
return settings == null ? null : settings
.getCustomCss();
}
}));
}
}

View File

@@ -0,0 +1,39 @@
package com.commafeed.frontend.references;
import java.io.IOException;
import org.apache.commons.lang.StringUtils;
import org.apache.wicket.request.resource.AbstractResource;
import org.apache.wicket.request.resource.IResource;
import org.apache.wicket.request.resource.ResourceReference;
@SuppressWarnings("serial")
public abstract class UserCustomCssReference extends ResourceReference {
public UserCustomCssReference() {
super(UserCustomCssReference.class, "custom.css");
}
@Override
public IResource getResource() {
return new AbstractResource() {
@Override
protected ResourceResponse newResourceResponse(Attributes attributes) {
ResourceResponse resourceResponse = new ResourceResponse();
resourceResponse.setContentType("text/css");
resourceResponse.setTextEncoding("UTF-8");
resourceResponse.setWriteCallback(new WriteCallback() {
@Override
public void writeData(Attributes attributes)
throws IOException {
attributes.getResponse().write(
StringUtils.trimToEmpty(getCss()));
}
});
return resourceResponse;
}
};
}
protected abstract String getCss();
}

View File

@@ -2,28 +2,31 @@ package com.commafeed.frontend.references.angularui;
import java.util.Arrays;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.request.resource.JavaScriptResourceReference;
import com.commafeed.frontend.utils.WicketUtils;
import com.commafeed.frontend.references.angular.AngularReference;
import de.agilecoders.wicket.webjars.request.resource.WebjarsJavaScriptResourceReference;
public class AngularUIReference extends WebjarsJavaScriptResourceReference {
public class AngularUIReference extends JavaScriptResourceReference {
private static final long serialVersionUID = 1L;
public static final AngularUIReference INSTANCE = new AngularUIReference();
private AngularUIReference() {
super("/angular-ui/current/angular-ui.js");
super(AngularUIReference.class, "angular-ui.js");
}
@SuppressWarnings("unchecked")
@Override
public Iterable<? extends HeaderItem> getDependencies() {
return Arrays
.asList(WicketUtils
.buildCssWebJarHeaderItem("/angular-ui/current/angular-ui.css"));
return Arrays.asList(JavaScriptHeaderItem
.forReference(AngularReference.INSTANCE), CssHeaderItem
.forReference(new CssResourceReference(
AngularUIReference.class, "angular-ui.css")));
}
public static void renderHead(final IHeaderResponse response) {

View File

@@ -0,0 +1,50 @@
/**
* import components to builds angular-ui.css
*/
/* ui-reset */
.ui-resetwrap {
position: relative;
display: inline-block;
}
.ui-reset {
position: absolute;
top: 0;
right: 0;
z-index: 2;
display: none;
height: 100%;
cursor: pointer;
}
.ui-resetwrap:hover .ui-reset {
display: block;
}
/* ui-currency */
.ui-currency-pos {
color: green;
}
.ui-currency-neg {
color: red;
}
.ui-currency-zero {
color: blue;
}
.ui-currency-pos.ui-bignum,
.ui-currency-neg.ui-smallnum {
font-size: 110%;
}
/* highlight */
.ui-match {
background: yellow;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
package com.commafeed.frontend.references.codemirror;
import java.util.Arrays;
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import de.agilecoders.wicket.webjars.request.resource.WebjarsJavaScriptResourceReference;
public class CodeMirrorCssReference extends WebjarsJavaScriptResourceReference {
private static final long serialVersionUID = 1L;
public static final CodeMirrorCssReference INSTANCE = new CodeMirrorCssReference();
private CodeMirrorCssReference() {
super("/codemirror/current/mode/css/css.js");
}
@Override
public Iterable<? extends HeaderItem> getDependencies() {
return Arrays.asList(JavaScriptHeaderItem
.forReference(CodeMirrorReference.INSTANCE));
}
public static void renderHead(final IHeaderResponse response) {
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
}
}

View File

@@ -0,0 +1,32 @@
package com.commafeed.frontend.references.codemirror;
import java.util.Arrays;
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import com.commafeed.frontend.utils.WicketUtils;
import de.agilecoders.wicket.webjars.request.resource.WebjarsJavaScriptResourceReference;
public class CodeMirrorReference extends WebjarsJavaScriptResourceReference {
private static final long serialVersionUID = 1L;
public static final CodeMirrorReference INSTANCE = new CodeMirrorReference();
private CodeMirrorReference() {
super("/codemirror/current/lib/codemirror.js");
}
@Override
public Iterable<? extends HeaderItem> getDependencies() {
return Arrays
.asList(WicketUtils
.buildCssWebJarHeaderItem("/codemirror/current/lib/codemirror.css"));
}
public static void renderHead(final IHeaderResponse response) {
response.render(JavaScriptHeaderItem.forReference(INSTANCE));
}
}

View File

@@ -21,6 +21,7 @@ public class SettingsREST extends AbstractREST {
UserSettings settings = userSettingsService.findByUser(getUser());
if (settings != null) {
s.setReadingMode(settings.getReadingMode().name());
s.setCustomCss(settings.getCustomCss());
} else {
s.setReadingMode(ReadingMode.unread.name());
}
@@ -38,6 +39,7 @@ public class SettingsREST extends AbstractREST {
s.setUser(getUser());
}
s.setReadingMode(ReadingMode.valueOf(settings.getReadingMode()));
s.setCustomCss(settings.getCustomCss());
userSettingsService.saveOrUpdate(s);
return Response.ok(Status.OK).build();

View File

@@ -12,7 +12,7 @@
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="settings"><i class="icon-cog"></i> {{session.name}} <span class="caret"></span></a>
<ul class="dropdown-menu pull-right">
<li><a href="settings"><i class="icon-wrench"></i> Settings</a></li>
<li><a ng-click="toSettings()"><i class="icon-wrench"></i> Settings</a></li>
<li ng-show="session.admin"><a ng-click="toAdmin()"><i class="icon-edit"></i> Admin</a></li>
<li class="divider"></li>
<li><a href="logout"><i class="icon-user"></i> Logout</a></li>

View File

@@ -342,4 +342,22 @@ module.controller('ManageUserCtrl', function($scope, $state, $stateParams,
}
});
};
});
module.controller('SettingsCtrl', function($scope, $location, SettingsService) {
$scope.settingsService = SettingsService;
$scope.codeMirrorConfig = {
mode : 'css',
lineNumbers : true
};
$scope.cancel = function() {
SettingsService.init(function() {
$location.path('/');
});
};
$scope.save = function() {
SettingsService.save(function() {
$location.path('/');
});
};
});

View File

@@ -232,6 +232,9 @@ module.directive('toolbar', function($state, $stateParams, $route, $location,
$scope.toAdmin = function() {
$location.path('admin');
};
$scope.toSettings = function() {
$location.path('settings');
};
},
link : function($scope, element) {
element.find('.read-mode button').bind('click', function() {

View File

@@ -39,6 +39,12 @@ app.config(function($routeProvider, $stateProvider, $urlRouterProvider) {
templateUrl : 'templates/admin.useredit.html',
controller : 'ManageUserCtrl'
});
$stateProvider.state('settings', {
url : '/settings',
templateUrl : 'templates/settings.html',
controller : 'SettingsCtrl'
});
$urlRouterProvider.when('/', '/feeds/view/category/all');
$urlRouterProvider.when('/admin', '/admin/user/list');

View File

@@ -162,12 +162,22 @@ module.factory('EntryService', function($resource, $http) {
module.factory('SettingsService', function($resource) {
var s = {};
s.settings = {};
$resource('rest/settings/get').get(function(data) {
s.settings = data;
});
s.save = function() {
$resource('rest/settings/save').save(s.settings);
s.save = function(callback) {
$resource('rest/settings/save').save(s.settings, function(data) {
if (callback) {
callback(data);
}
});
};
s.init = function(callback) {
$resource('rest/settings/get').get(function(data) {
s.settings = data;
if (callback) {
callback(data);
}
});
};
s.init();
return s;
});

View File

@@ -0,0 +1,28 @@
<div class="container settings">
<div class="page-header">
<h1>Settings</h1>
</div>
<div class="row">
<div class="span2">
<ul class="nav nav-pills nav-stacked">
<li class="active"><a href="#general" data-toggle="pill">General</a></li>
<li><a href="#custom-css" data-toggle="pill" ng-click="refreshCodemirror=!refreshCodemirror">Custom CSS</a></li>
</ul>
</div>
<div class="span10">
<div class="tab-content">
<div class="tab-pane active" id="general" style="height: 500px">
Placeholder for general settings
</div>
<div class="tab-pane" id="custom-css">
<textarea ui-codemirror="codeMirrorConfig" ng-model="settingsService.settings.customCss" ui-refresh="refreshCodemirror">
</textarea>
</div>
</div>
</div>
</div>
<div class="form-actions">
<button type="button" class="btn btn-primary" ng-click="save()">Save</button>
<button type="button" class="btn" ng-click="cancel()">Cancel</button>
</div>
</div>