mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Able to edit avatar while uploading
This commit is contained in:
parent
17ab9bd963
commit
cbfede1853
@ -209,6 +209,7 @@ public class OneUrlMapper extends CompoundRequestMapper {
|
||||
add(new OnePageMapper("projects/${project}/builds", BuildListPage.class));
|
||||
|
||||
add(new OnePageMapper("projects/${project}/settings/general", GeneralSettingPage.class));
|
||||
add(new OnePageMapper("projects/${project}/settings/avatar", io.onedev.server.web.page.project.setting.avatar.AvatarEditPage.class));
|
||||
add(new OnePageMapper("projects/${project}/settings/teams", TeamListPage.class));
|
||||
add(new OnePageMapper("projects/${project}/settings/teams/new", NewTeamPage.class));
|
||||
add(new OnePageMapper("projects/${project}/settings/teams/${team}", TeamEditPage.class));
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
package io.onedev.server.web.asset.cropper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.request.resource.CssResourceReference;
|
||||
import org.apache.wicket.request.resource.JavaScriptResourceReference;
|
||||
|
||||
public class CropperResourceReference extends JavaScriptResourceReference {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CropperResourceReference() {
|
||||
super(CropperResourceReference.class, "cropper.min.js");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeaderItem> getDependencies() {
|
||||
List<HeaderItem> dependencies = super.getDependencies();
|
||||
dependencies.add(CssHeaderItem.forReference(new CssResourceReference(CropperResourceReference.class, "cropper.min.css")));
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
}
|
||||
9
core/src/main/java/io/onedev/server/web/asset/cropper/cropper.min.css
vendored
Normal file
9
core/src/main/java/io/onedev/server/web/asset/cropper/cropper.min.css
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Cropper.js v1.4.3
|
||||
* https://fengyuanchen.github.io/cropperjs
|
||||
*
|
||||
* Copyright 2015-present Chen Fengyuan
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: 2018-10-24T13:07:11.429Z
|
||||
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline-color:rgba(51,153,255,.75);outline:1px solid #39f;overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}
|
||||
10
core/src/main/java/io/onedev/server/web/asset/cropper/cropper.min.js
vendored
Normal file
10
core/src/main/java/io/onedev/server/web/asset/cropper/cropper.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,13 @@
|
||||
package io.onedev.server.web.component.avatarupload;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
|
||||
import io.onedev.server.web.util.AjaxPayload;
|
||||
|
||||
public class AvatarFileSelected extends AjaxPayload {
|
||||
|
||||
public AvatarFileSelected(AjaxRequestTarget target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
<wicket:panel>
|
||||
<div class="avatar-upload">
|
||||
<input type="text" wicket:id="data">
|
||||
<input wicket:id="fileInput" type="file" accept="image/*">
|
||||
<label wicket:id="fileLabel"><i class="fa fa-file-image-o"></i> Select file...</label>
|
||||
<div class="preview clearfix">
|
||||
<div class="cropping pull-left"><img></div>
|
||||
<div class="cropped pull-left"><img></div>
|
||||
</div>
|
||||
</div>
|
||||
</wicket:panel>
|
||||
@ -0,0 +1,116 @@
|
||||
package io.onedev.server.web.component.avatarupload;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.event.Broadcast;
|
||||
import org.apache.wicket.markup.ComponentTag;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
|
||||
import org.apache.wicket.markup.html.WebComponent;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.form.FormComponentPanel;
|
||||
import org.apache.wicket.markup.html.form.TextField;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
|
||||
import io.onedev.server.web.behavior.AbstractPostAjaxBehavior;
|
||||
import io.onedev.utils.FileUtils;
|
||||
import io.onedev.utils.StringUtils;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AvatarUploadField extends FormComponentPanel<String> {
|
||||
|
||||
private TextField<String> dataField;
|
||||
|
||||
private AbstractPostAjaxBehavior behavior;
|
||||
|
||||
public AvatarUploadField(String id, IModel<String> model) {
|
||||
super(id, model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(dataField = new TextField<String>("data", Model.of(getModelObject())));
|
||||
|
||||
WebComponent fileInput = new WebComponent("fileInput");
|
||||
fileInput.setOutputMarkupId(true);
|
||||
add(fileInput);
|
||||
|
||||
add(new WebMarkupContainer("fileLabel") {
|
||||
|
||||
@Override
|
||||
protected void onComponentTag(ComponentTag tag) {
|
||||
super.onComponentTag(tag);
|
||||
tag.put("for", fileInput.getMarkupId());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
add(behavior = new AbstractPostAjaxBehavior() {
|
||||
|
||||
@Override
|
||||
protected void respond(AjaxRequestTarget target) {
|
||||
send(AvatarUploadField.this, Broadcast.BUBBLE, new AvatarFileSelected(target));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void convertInput() {
|
||||
setConvertedInput(dataField.getConvertedInput());
|
||||
}
|
||||
|
||||
public static void writeToFile(File file, @Nullable String avatarData) {
|
||||
if (avatarData != null) {
|
||||
byte[] imageBytes = DatatypeConverter.parseBase64Binary(StringUtils.substringAfter(avatarData, ","));
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
|
||||
ImageIO.write(image, "jpeg", file);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (file.exists()) {
|
||||
FileUtils.deleteFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String readFromFile(File file) {
|
||||
if (file.exists()) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try {
|
||||
ImageIO.write(ImageIO.read(file), "jpeg", baos);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return "data:image/jpeg;base64," + DatatypeConverter.printBase64Binary(baos.toByteArray());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
response.render(JavaScriptHeaderItem.forReference(new AvatarUploadResourceReference()));
|
||||
|
||||
String script = String.format("onedev.server.avatarUpload.onDomReady('%s', %s);",
|
||||
getMarkupId(), behavior.getCallbackFunction());
|
||||
|
||||
response.render(OnDomReadyHeaderItem.forScript(script));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package io.onedev.server.web.component.avatarupload;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
|
||||
import io.onedev.server.web.asset.cropper.CropperResourceReference;
|
||||
import io.onedev.server.web.page.base.BaseDependentCssResourceReference;
|
||||
import io.onedev.server.web.page.base.BaseDependentResourceReference;
|
||||
|
||||
public class AvatarUploadResourceReference extends BaseDependentResourceReference {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AvatarUploadResourceReference() {
|
||||
super(AvatarUploadResourceReference.class, "avatar-upload.js");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HeaderItem> getDependencies() {
|
||||
List<HeaderItem> dependencies = super.getDependencies();
|
||||
dependencies.add(JavaScriptHeaderItem.forReference(new CropperResourceReference()));
|
||||
dependencies.add(CssHeaderItem.forReference(new BaseDependentCssResourceReference(
|
||||
AvatarUploadResourceReference.class, "avatar-upload.css")));
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
.avatar-upload .preview {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.avatar-upload .cropping {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
}
|
||||
.avatar-upload .cropping img {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.avatar-upload .cropped {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
margin-left: 20px;
|
||||
border-radius: 1000px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.avatar-upload input[type="text"] {
|
||||
display: none;
|
||||
}
|
||||
.avatar-upload input[type="file"] {
|
||||
width: 0.1px;
|
||||
height: 0.1px;
|
||||
opacity: 0;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
}
|
||||
.avatar-upload input[type="file"] + label {
|
||||
font-weight: normal;
|
||||
border: 1px solid #CECECE;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
padding: 6px 12px;
|
||||
}
|
||||
.avatar-upload input[type="file"]:focus + label {
|
||||
outline: 1px dotted blue;
|
||||
outline: -webkit-focus-ring-color auto 5px;
|
||||
}
|
||||
.avatar-upload.no-avatar .preview {
|
||||
display: none;
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
onedev.server.avatarUpload = {
|
||||
onDomReady: function(containerId, callback) {
|
||||
var $container = $("#" + containerId + ">.avatar-upload");
|
||||
var $data = $container.find("input[type=text]")
|
||||
var $image = $container.find(".cropping img");
|
||||
var $file = $container.find("input[type=file]");
|
||||
if ($data.val()) {
|
||||
$image.attr("src", $data.val());
|
||||
} else {
|
||||
$container.addClass("no-avatar");
|
||||
}
|
||||
function preview() {
|
||||
if ($image[0].hasAttribute("src")) {
|
||||
if ($image[0].cropper) {
|
||||
$image[0].cropper.replace($image.attr("src"));
|
||||
} else {
|
||||
new Cropper($image[0], {
|
||||
aspectRatio: 1,
|
||||
autoCropArea: 1,
|
||||
crop: function(event) {
|
||||
var $cropped = $container.find(".cropped");
|
||||
var data = this.cropper.getCroppedCanvas({
|
||||
width: $cropped.width(),
|
||||
height: $cropped.height()
|
||||
}).toDataURL("image/jpeg");
|
||||
$cropped.find("img").attr("src", data);
|
||||
$data.val(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
preview();
|
||||
|
||||
$file.change(function() {
|
||||
if ($file[0].files && $file[0].files.length != 0) {
|
||||
var file = $file[0].files[0];
|
||||
var reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.addEventListener("load", function () {
|
||||
callback();
|
||||
$container.removeClass("no-avatar");
|
||||
$image.attr("src", reader.result);
|
||||
preview();
|
||||
}, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package io.onedev.server.web.component.project.avatar;
|
||||
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.markup.ComponentTag;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
@ -13,30 +12,16 @@ import io.onedev.server.web.util.avatar.AvatarManager;
|
||||
@SuppressWarnings("serial")
|
||||
public class ProjectAvatar extends WebComponent {
|
||||
|
||||
private final Long projectId;
|
||||
|
||||
private String url;
|
||||
|
||||
public ProjectAvatar(String id, Project project) {
|
||||
super(id);
|
||||
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
projectId = project.getId();
|
||||
url = avatarManager.getAvatarUrl(project.getFacade());
|
||||
url = getAvatarManager().getAvatarUrl(project.getFacade());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(IEvent<?> event) {
|
||||
super.onEvent(event);
|
||||
|
||||
if (event.getPayload() instanceof ProjectAvatarChanged) {
|
||||
ProjectAvatarChanged avatarChanged = (ProjectAvatarChanged) event.getPayload();
|
||||
if (avatarChanged.getProject().getId().equals(projectId)) {
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
url = avatarManager.getAvatarUrl(avatarChanged.getProject().getFacade());
|
||||
avatarChanged.getHandler().add(this);
|
||||
}
|
||||
}
|
||||
private AvatarManager getAvatarManager() {
|
||||
return OneDev.getInstance(AvatarManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
package io.onedev.server.web.component.project.avatar;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
|
||||
import io.onedev.server.model.Project;
|
||||
import io.onedev.server.web.util.AjaxPayload;
|
||||
|
||||
public class ProjectAvatarChanged extends AjaxPayload {
|
||||
|
||||
private final Project project;
|
||||
|
||||
public ProjectAvatarChanged(AjaxRequestTarget target, Project project) {
|
||||
super(target);
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return project;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package io.onedev.server.web.component.project.avatar;
|
||||
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.markup.ComponentTag;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
@ -18,8 +17,6 @@ import io.onedev.server.web.util.avatar.AvatarManager;
|
||||
@SuppressWarnings("serial")
|
||||
public class ProjectAvatarLink extends ViewStateAwarePageLink<Void> {
|
||||
|
||||
private final Long projectId;
|
||||
|
||||
private final PageParameters params;
|
||||
|
||||
private String url;
|
||||
@ -30,7 +27,6 @@ public class ProjectAvatarLink extends ViewStateAwarePageLink<Void> {
|
||||
super(id, ProjectBlobPage.class);
|
||||
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
projectId = project.getId();
|
||||
params = ProjectPage.paramsOf(project);
|
||||
url = avatarManager.getAvatarUrl(project.getFacade());
|
||||
tooltip = project.getName();
|
||||
@ -46,20 +42,6 @@ public class ProjectAvatarLink extends ViewStateAwarePageLink<Void> {
|
||||
return Model.of("<img src='" + url + "' class='project-avatar'></img>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(IEvent<?> event) {
|
||||
super.onEvent(event);
|
||||
|
||||
if (event.getPayload() instanceof ProjectAvatarChanged) {
|
||||
ProjectAvatarChanged avatarChanged = (ProjectAvatarChanged) event.getPayload();
|
||||
if (avatarChanged.getProject().getId().equals(projectId)) {
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
url = avatarManager.getAvatarUrl(avatarChanged.getProject().getFacade());
|
||||
avatarChanged.getHandler().add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onComponentTag(ComponentTag tag) {
|
||||
super.onComponentTag(tag);
|
||||
|
||||
@ -2,7 +2,6 @@ package io.onedev.server.web.component.user.avatar;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.markup.ComponentTag;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
@ -17,51 +16,27 @@ import io.onedev.server.web.util.avatar.AvatarManager;
|
||||
@SuppressWarnings("serial")
|
||||
public class UserAvatar extends WebComponent {
|
||||
|
||||
private final Long userId;
|
||||
|
||||
private String url;
|
||||
|
||||
public UserAvatar(String id, @Nullable User user) {
|
||||
super(id);
|
||||
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
if (user == null) {
|
||||
userId = null;
|
||||
} else if (user.getId() == null) {
|
||||
userId = null;
|
||||
} else {
|
||||
userId = user.getId();
|
||||
}
|
||||
url = avatarManager.getAvatarUrl(user!=null?user.getFacade():null);
|
||||
url = getAvatarManager().getAvatarUrl(user!=null?user.getFacade():null);
|
||||
}
|
||||
|
||||
public UserAvatar(String id, PersonIdent person) {
|
||||
super(id);
|
||||
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
|
||||
User user = OneDev.getInstance(UserManager.class).find(person);
|
||||
if (user != null) {
|
||||
userId = user.getId();
|
||||
url = avatarManager.getAvatarUrl(user.getFacade());
|
||||
url = getAvatarManager().getAvatarUrl(user.getFacade());
|
||||
} else {
|
||||
userId = null;
|
||||
url = avatarManager.getAvatarUrl(person);
|
||||
url = getAvatarManager().getAvatarUrl(person);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(IEvent<?> event) {
|
||||
super.onEvent(event);
|
||||
|
||||
if (event.getPayload() instanceof UserAvatarChanged) {
|
||||
UserAvatarChanged avatarChanged = (UserAvatarChanged) event.getPayload();
|
||||
if (avatarChanged.getUser().getId().equals(userId)) {
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
url = avatarManager.getAvatarUrl(avatarChanged.getUser().getFacade());
|
||||
avatarChanged.getHandler().add(this);
|
||||
}
|
||||
}
|
||||
private AvatarManager getAvatarManager() {
|
||||
return OneDev.getInstance(AvatarManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
package io.onedev.server.web.component.user.avatar;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
|
||||
import io.onedev.server.model.User;
|
||||
import io.onedev.server.web.util.AjaxPayload;
|
||||
|
||||
public class UserAvatarChanged extends AjaxPayload {
|
||||
|
||||
private final User user;
|
||||
|
||||
public UserAvatarChanged(AjaxRequestTarget target, User user) {
|
||||
super(target);
|
||||
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ package io.onedev.server.web.component.user.avatar;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.wicket.behavior.AttributeAppender;
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.markup.ComponentTag;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
@ -23,8 +22,6 @@ import io.onedev.server.web.util.avatar.AvatarManager;
|
||||
@SuppressWarnings("serial")
|
||||
public class UserAvatarLink extends ViewStateAwarePageLink<Void> {
|
||||
|
||||
private final Long userId;
|
||||
|
||||
private final PageParameters params;
|
||||
|
||||
private final String tooltip;
|
||||
@ -40,13 +37,10 @@ public class UserAvatarLink extends ViewStateAwarePageLink<Void> {
|
||||
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
if (user == null) {
|
||||
userId = null;
|
||||
params = new PageParameters();
|
||||
} else if (user.getId() == null) {
|
||||
userId = null;
|
||||
params = new PageParameters();
|
||||
} else {
|
||||
userId = user.getId();
|
||||
params = UserPage.paramsOf(user);
|
||||
}
|
||||
this.tooltip = tooltip;
|
||||
@ -64,11 +58,9 @@ public class UserAvatarLink extends ViewStateAwarePageLink<Void> {
|
||||
|
||||
User user = OneDev.getInstance(UserManager.class).find(person);
|
||||
if (user != null) {
|
||||
userId = user.getId();
|
||||
params = UserPage.paramsOf(user);
|
||||
url = avatarManager.getAvatarUrl(user.getFacade());
|
||||
} else {
|
||||
userId = null;
|
||||
params = new PageParameters();
|
||||
url = avatarManager.getAvatarUrl(person);
|
||||
}
|
||||
@ -86,20 +78,6 @@ public class UserAvatarLink extends ViewStateAwarePageLink<Void> {
|
||||
return Model.of("<img src='" + url + "' class='avatar'></img>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(IEvent<?> event) {
|
||||
super.onEvent(event);
|
||||
|
||||
if (event.getPayload() instanceof UserAvatarChanged) {
|
||||
UserAvatarChanged avatarChanged = (UserAvatarChanged) event.getPayload();
|
||||
if (avatarChanged.getUser().getId().equals(userId)) {
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
url = avatarManager.getAvatarUrl(avatarChanged.getUser().getFacade());
|
||||
avatarChanged.getHandler().add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onComponentTag(ComponentTag tag) {
|
||||
super.onComponentTag(tag);
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<ul class="nav navbar-nav tabs">
|
||||
<li wicket:id="navProjects"><a wicket:id="link">Projects</a></li>
|
||||
<li wicket:id="navContributions"><a wicket:id="link"><span wicket:id="label"></span></a></li>
|
||||
<li wicket:id="navUsers"><a wicket:id="link">Users</a></li>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
height: 24px;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.navbar a {
|
||||
.navbar .tabs a {
|
||||
font-size: 16px;
|
||||
}
|
||||
.navbar-nav>li>a.avatar {
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
<wicket:extend>
|
||||
<div class="avatar-edit">
|
||||
<img wicket:id="avatar"></img>
|
||||
<form wicket:id="form">
|
||||
<div wicket:id="feedback"></div>
|
||||
<div wicket:id="file"></div>
|
||||
<div class="actions">
|
||||
<button wicket:id="useUploaded" class="btn btn-primary dirty-aware">Use Uploaded</button>
|
||||
<a wicket:id="useDefault" class="btn btn-default">Use Default</a>
|
||||
</div>
|
||||
</form>
|
||||
<div class="help-block">
|
||||
The image size should be less than <span wicket:id="maxSize"></span>M bytes.
|
||||
<div class="current">
|
||||
<div class="title">Current avatar</div>
|
||||
<img wicket:id="avatar"/>
|
||||
<a wicket:id="useDefault" class="btn btn-default"><i class="fa fa-undo"/> Use Default</a>
|
||||
</div>
|
||||
<div class="use-uploaded">
|
||||
<div class="title">Upload avatar</div>
|
||||
<form wicket:id="form">
|
||||
<div wicket:id="avatar"></div>
|
||||
<button wicket:id="upload" type="submit" class="btn btn-default"><i class="fa fa-upload"></i> Upload</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</wicket:extend>
|
||||
@ -1,39 +1,31 @@
|
||||
package io.onedev.server.web.page.project.setting.avatar;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
|
||||
import org.apache.wicket.event.Broadcast;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.markup.html.form.Button;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.form.upload.FileUpload;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.model.PropertyModel;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.apache.wicket.util.lang.Bytes;
|
||||
|
||||
import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.web.component.dropzonefield.DropzoneField;
|
||||
import io.onedev.server.web.component.avatarupload.AvatarFileSelected;
|
||||
import io.onedev.server.web.component.avatarupload.AvatarUploadField;
|
||||
import io.onedev.server.web.component.project.avatar.ProjectAvatar;
|
||||
import io.onedev.server.web.component.project.avatar.ProjectAvatarChanged;
|
||||
import io.onedev.server.web.page.project.setting.ProjectSettingPage;
|
||||
import io.onedev.server.web.util.avatar.AvatarManager;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AvatarEditPage extends ProjectSettingPage {
|
||||
|
||||
private static final int MAX_IMAGE_SIZE = 5;
|
||||
|
||||
private Collection<FileUpload> uploads;
|
||||
private String uploadedAvatarData;
|
||||
|
||||
public AvatarEditPage(PageParameters params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
private AvatarManager getAvatarManager() {
|
||||
return OneDev.getInstance(AvatarManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
@ -41,68 +33,51 @@ public class AvatarEditPage extends ProjectSettingPage {
|
||||
|
||||
add(new ProjectAvatar("avatar", getProject()));
|
||||
|
||||
Form<?> form = new Form<Void>("form");
|
||||
add(form);
|
||||
|
||||
form.add(new NotificationPanel("feedback", form));
|
||||
form.setMaxSize(Bytes.megabytes(MAX_IMAGE_SIZE));
|
||||
form.setOutputMarkupId(true);
|
||||
|
||||
form.setMultiPart(true);
|
||||
|
||||
IModel<Collection<FileUpload>> model = new PropertyModel<>(this, "uploads");
|
||||
|
||||
DropzoneField dropzoneField = new DropzoneField("file", model, "image/*", 1, MAX_IMAGE_SIZE);
|
||||
dropzoneField.setRequired(true).setLabel(Model.of("Image"));
|
||||
form.add(dropzoneField);
|
||||
|
||||
form.add(new AjaxButton("useUploaded") {
|
||||
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onError(target, form);
|
||||
target.add(form);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onSubmit(target, form);
|
||||
FileUpload upload = uploads.iterator().next();
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
avatarManager.useAvatar(projectModel.getObject().getFacade(), upload);
|
||||
send(getPage(), Broadcast.BREADTH, new ProjectAvatarChanged(target, projectModel.getObject()));
|
||||
target.add(form);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
form.add(new AjaxLink<Void>("useDefault") {
|
||||
add(new Link<Void>("useDefault") {
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
setVisible(avatarManager.getUploaded(projectModel.getObject().getFacade()).exists());
|
||||
setVisible(getAvatarManager().getUploaded(getProject().getFacade()).exists());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
avatarManager.useAvatar(projectModel.getObject().getFacade(), null);
|
||||
target.add(form);
|
||||
send(getPage(), Broadcast.BREADTH, new ProjectAvatarChanged(target, projectModel.getObject()));
|
||||
public void onClick() {
|
||||
getAvatarManager().useAvatar(getProject().getFacade(), null);
|
||||
setResponsePage(AvatarEditPage.class, AvatarEditPage.paramsOf(getProject()));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Button uploadButton = new Button("upload");
|
||||
uploadButton.setVisible(false).setOutputMarkupPlaceholderTag(true);
|
||||
|
||||
add(new Label("maxSize", MAX_IMAGE_SIZE));
|
||||
Form<?> form = new Form<Void>("form") {
|
||||
|
||||
@Override
|
||||
protected void onSubmit() {
|
||||
super.onSubmit();
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
avatarManager.useAvatar(getProject().getFacade(), uploadedAvatarData);
|
||||
setResponsePage(AvatarEditPage.class, AvatarEditPage.paramsOf(getProject()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(IEvent<?> event) {
|
||||
super.onEvent(event);
|
||||
if (event.getPayload() instanceof AvatarFileSelected) {
|
||||
AvatarFileSelected avatarFileSelected = (AvatarFileSelected) event.getPayload();
|
||||
uploadButton.setVisible(true);
|
||||
avatarFileSelected.getHandler().add(uploadButton);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PropertyModel<String> avatarDataModel = new PropertyModel<String>(this, "uploadedAvatarData");
|
||||
form.add(new AvatarUploadField("avatar", avatarDataModel));
|
||||
form.add(uploadButton);
|
||||
|
||||
setOutputMarkupId(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPermitted() {
|
||||
return SecurityUtils.canAdministrate(getProject().getFacade());
|
||||
add(form);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -66,12 +66,24 @@
|
||||
#project-setting .authorization.list .head .select2-container {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
#project-setting .avatar-edit img.project-avatar {
|
||||
height: 240px;
|
||||
width: 240px;
|
||||
#project-setting .avatar-edit .title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
#project-setting .avatar-edit .upload {
|
||||
margin-right: 8px;
|
||||
#project-setting .avatar-edit>.current {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
}
|
||||
#project-setting .avatar-edit .current img {
|
||||
height: 240px;
|
||||
width: 240px;
|
||||
display: block;
|
||||
}
|
||||
#project-setting .avatar-edit .current a {
|
||||
margin-top: 20px;
|
||||
}
|
||||
#project-setting .avatar-edit form>button {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
<wicket:extend>
|
||||
<a wicket:id="test">test</a>
|
||||
<form wicket:id="form">
|
||||
<div wicket:id="avatar" style="margin-bottom: 20px;"></div>
|
||||
<input type="submit" class="form-control" value="Save">
|
||||
</form>
|
||||
</wicket:extend>
|
||||
@ -1,84 +1,39 @@
|
||||
package io.onedev.server.web.page.test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.model.Model;
|
||||
|
||||
import io.onedev.server.web.component.avatarupload.AvatarUploadField;
|
||||
import io.onedev.server.web.page.base.BasePage;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TestPage extends BasePage {
|
||||
|
||||
private AvatarUploadField avatarUpload;
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(new Link<Void>("test") {
|
||||
|
||||
String avatarData = AvatarUploadField.readFromFile(new File("w:\\temp\\avatar.jpg"));
|
||||
Form<?> form = new Form<Void>("form") {
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
/*
|
||||
for (int k=0; k<100; k++) {
|
||||
UnitOfWork unitOfWork = OneDev.getInstance(UnitOfWork.class);
|
||||
unitOfWork.begin();
|
||||
Session session = unitOfWork.getSession();
|
||||
session.beginTransaction();
|
||||
Project project = OneDev.getInstance(ProjectManager.class).load(1L);
|
||||
User user = OneDev.getInstance(UserManager.class).load(1L);
|
||||
Milestone milestone = OneDev.getInstance(MilestoneManager.class).load(1L);
|
||||
try {
|
||||
for (int i=0; i<10000; i++) {
|
||||
long j = k*10000 +i;
|
||||
Issue issue = new Issue();
|
||||
issue.setProject(project);
|
||||
issue.setTitle("Issue " + j);
|
||||
issue.setNumber(j+2);
|
||||
if (j<10000)
|
||||
issue.setState("Open");
|
||||
else
|
||||
issue.setState("Closed");
|
||||
if (j<1000)
|
||||
issue.setMilestone(milestone);
|
||||
issue.setSubmitDate(new Date());
|
||||
issue.setSubmitter(user);
|
||||
issue.setUUID(UUID.randomUUID().toString());
|
||||
LastActivity lastActivity = new LastActivity();
|
||||
lastActivity.setDescription("submitted");
|
||||
lastActivity.setUser(issue.getSubmitter());
|
||||
lastActivity.setDate(issue.getSubmitDate());
|
||||
issue.setLastActivity(lastActivity);
|
||||
session.save(issue);
|
||||
IssueFieldUnary unary = new IssueFieldUnary();
|
||||
unary.setIssue(issue);
|
||||
unary.setName("Type");
|
||||
unary.setType(InputSpec.ENUMERATION);
|
||||
if (i%4 == 0) {
|
||||
unary.setOrdinal(1L);
|
||||
unary.setValue("Bug");
|
||||
} else if (i%4 == 1) {
|
||||
unary.setOrdinal(2L);
|
||||
unary.setValue("Task");
|
||||
} else if (i%4 == 2) {
|
||||
unary.setOrdinal(3L);
|
||||
unary.setValue("New Feature");
|
||||
} else {
|
||||
unary.setOrdinal(4L);
|
||||
unary.setValue("Improvement");
|
||||
}
|
||||
session.save(unary);
|
||||
}
|
||||
session.flush();
|
||||
session.getTransaction().commit();
|
||||
} finally {
|
||||
unitOfWork.end();
|
||||
}
|
||||
System.out.println(k);
|
||||
}
|
||||
*/
|
||||
protected void onSubmit() {
|
||||
super.onSubmit();
|
||||
AvatarUploadField.writeToFile(new File("w:\\temp\\avatar.jpg"), avatarUpload.getModelObject());
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
form.add(avatarUpload = new AvatarUploadField("avatar", Model.of(avatarData)));
|
||||
avatarUpload.setRequired(true);
|
||||
|
||||
add(form);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -6,7 +6,7 @@ import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.HeaderItem;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
|
||||
import io.onedev.server.web.asset.jqueryui.JQueryUIResourceReference;
|
||||
import io.onedev.server.web.asset.cropper.CropperResourceReference;
|
||||
import io.onedev.server.web.page.base.BaseDependentCssResourceReference;
|
||||
import io.onedev.server.web.page.base.BaseDependentResourceReference;
|
||||
|
||||
@ -21,7 +21,7 @@ public class TestResourceReference extends BaseDependentResourceReference {
|
||||
@Override
|
||||
public List<HeaderItem> getDependencies() {
|
||||
List<HeaderItem> dependencies = super.getDependencies();
|
||||
dependencies.add(JavaScriptHeaderItem.forReference(new JQueryUIResourceReference()));
|
||||
dependencies.add(JavaScriptHeaderItem.forReference(new CropperResourceReference()));
|
||||
dependencies.add(CssHeaderItem.forReference(new BaseDependentCssResourceReference(
|
||||
TestResourceReference.class, "test.css")));
|
||||
return dependencies;
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
<wicket:extend>
|
||||
<div class="avatar-edit">
|
||||
<img wicket:id="avatar"></img>
|
||||
<form wicket:id="form">
|
||||
<div wicket:id="feedback"></div>
|
||||
<div wicket:id="file"></div>
|
||||
<div class="actions">
|
||||
<button wicket:id="useUploaded" class="btn btn-primary dirty-aware">Use Uploaded</button>
|
||||
<a wicket:id="useDefault" class="btn btn-default">Use Default</a>
|
||||
</div>
|
||||
</form>
|
||||
<div class="help-block">
|
||||
The image size should be less than <span wicket:id="maxSize"></span>M bytes.
|
||||
<div class="current">
|
||||
<div class="title">Current avatar</div>
|
||||
<img wicket:id="avatar"/>
|
||||
<a wicket:id="useDefault" class="btn btn-default"><i class="fa fa-undo"/> Use Default</a>
|
||||
</div>
|
||||
<div class="use-uploaded">
|
||||
<div class="title">Upload avatar</div>
|
||||
<form wicket:id="form">
|
||||
<div wicket:id="avatar"></div>
|
||||
<button wicket:id="upload" type="submit" class="btn btn-default"><i class="fa fa-upload"></i> Upload</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</wicket:extend>
|
||||
@ -1,38 +1,31 @@
|
||||
package io.onedev.server.web.page.user;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
|
||||
import org.apache.wicket.event.Broadcast;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.markup.html.form.Button;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.form.upload.FileUpload;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.model.PropertyModel;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.apache.wicket.util.lang.Bytes;
|
||||
|
||||
import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.security.SecurityUtils;
|
||||
import io.onedev.server.web.component.dropzonefield.DropzoneField;
|
||||
import io.onedev.server.web.component.avatarupload.AvatarFileSelected;
|
||||
import io.onedev.server.web.component.avatarupload.AvatarUploadField;
|
||||
import io.onedev.server.web.component.user.avatar.UserAvatar;
|
||||
import io.onedev.server.web.component.user.avatar.UserAvatarChanged;
|
||||
import io.onedev.server.web.util.avatar.AvatarManager;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AvatarEditPage extends UserPage {
|
||||
|
||||
private static final int MAX_IMAGE_SIZE = 5;
|
||||
|
||||
private Collection<FileUpload> uploads;
|
||||
private String uploadedAvatarData;
|
||||
|
||||
public AvatarEditPage(PageParameters params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
private AvatarManager getAvatarManager() {
|
||||
return OneDev.getInstance(AvatarManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
@ -40,63 +33,51 @@ public class AvatarEditPage extends UserPage {
|
||||
|
||||
add(new UserAvatar("avatar", getUser()));
|
||||
|
||||
Form<?> form = new Form<Void>("form");
|
||||
add(form);
|
||||
|
||||
form.add(new NotificationPanel("feedback", form));
|
||||
form.setMaxSize(Bytes.megabytes(MAX_IMAGE_SIZE));
|
||||
form.setOutputMarkupId(true);
|
||||
|
||||
form.setMultiPart(true);
|
||||
|
||||
IModel<Collection<FileUpload>> model = new PropertyModel<>(this, "uploads");
|
||||
|
||||
DropzoneField dropzoneField = new DropzoneField("file", model, "image/*", 1, MAX_IMAGE_SIZE);
|
||||
dropzoneField.setRequired(true).setLabel(Model.of("Image"));
|
||||
form.add(dropzoneField);
|
||||
|
||||
form.add(new AjaxButton("useUploaded") {
|
||||
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onError(target, form);
|
||||
target.add(form);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onSubmit(target, form);
|
||||
FileUpload upload = uploads.iterator().next();
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
avatarManager.useAvatar(userModel.getObject().getFacade(), upload);
|
||||
send(getPage(), Broadcast.BREADTH, new UserAvatarChanged(target, userModel.getObject()));
|
||||
target.add(form);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
form.add(new AjaxLink<Void>("useDefault") {
|
||||
add(new Link<Void>("useDefault") {
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
super.onConfigure();
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
setVisible(avatarManager.getUploaded(userModel.getObject().getFacade()).exists());
|
||||
setVisible(getAvatarManager().getUploaded(getUser().getFacade()).exists());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
avatarManager.useAvatar(userModel.getObject().getFacade(), null);
|
||||
target.add(form);
|
||||
send(getPage(), Broadcast.BREADTH, new UserAvatarChanged(target, userModel.getObject()));
|
||||
public void onClick() {
|
||||
getAvatarManager().useAvatar(getUser().getFacade(), null);
|
||||
setResponsePage(AvatarEditPage.class, AvatarEditPage.paramsOf(getUser()));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Button uploadButton = new Button("upload");
|
||||
uploadButton.setVisible(false).setOutputMarkupPlaceholderTag(true);
|
||||
|
||||
add(new Label("maxSize", MAX_IMAGE_SIZE));
|
||||
Form<?> form = new Form<Void>("form") {
|
||||
|
||||
@Override
|
||||
protected void onSubmit() {
|
||||
super.onSubmit();
|
||||
AvatarManager avatarManager = OneDev.getInstance(AvatarManager.class);
|
||||
avatarManager.useAvatar(getUser().getFacade(), uploadedAvatarData);
|
||||
setResponsePage(AvatarEditPage.class, AvatarEditPage.paramsOf(getUser()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(IEvent<?> event) {
|
||||
super.onEvent(event);
|
||||
if (event.getPayload() instanceof AvatarFileSelected) {
|
||||
AvatarFileSelected avatarFileSelected = (AvatarFileSelected) event.getPayload();
|
||||
uploadButton.setVisible(true);
|
||||
avatarFileSelected.getHandler().add(uploadButton);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PropertyModel<String> avatarDataModel = new PropertyModel<String>(this, "uploadedAvatarData");
|
||||
form.add(new AvatarUploadField("avatar", avatarDataModel));
|
||||
form.add(uploadButton);
|
||||
|
||||
setOutputMarkupId(true);
|
||||
add(form);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -18,15 +18,6 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
#user .avatar-edit img.avatar {
|
||||
height: 240px;
|
||||
width: 240px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
#user .avatar-edit .upload {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
#user .project.list .head .select2-container {
|
||||
width: 240px;
|
||||
}
|
||||
@ -35,6 +26,28 @@
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
#user .avatar-edit .title {
|
||||
margin-bottom: 20px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
#user .avatar-edit>.current {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
}
|
||||
#user .avatar-edit .current img {
|
||||
height: 240px;
|
||||
width: 240px;
|
||||
display: block;
|
||||
}
|
||||
#user .avatar-edit .current a {
|
||||
margin-top: 20px;
|
||||
}
|
||||
#user .avatar-edit form>button {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.user.list .actions a {
|
||||
color: #666;
|
||||
}
|
||||
@ -48,4 +61,4 @@
|
||||
.token-generate .token-value a {
|
||||
color: #444;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,6 @@ import java.io.File;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.wicket.markup.html.form.upload.FileUpload;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
|
||||
import io.onedev.server.util.facade.ProjectFacade;
|
||||
@ -34,9 +33,9 @@ public interface AvatarManager {
|
||||
*/
|
||||
String getAvatarUrl(PersonIdent person);
|
||||
|
||||
void useAvatar(UserFacade user, @Nullable FileUpload upload);
|
||||
void useAvatar(UserFacade user, @Nullable String avatarData);
|
||||
|
||||
void useAvatar(ProjectFacade project, @Nullable FileUpload upload);
|
||||
void useAvatar(ProjectFacade project, @Nullable String avatarData);
|
||||
|
||||
File getUploaded(UserFacade user);
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.wicket.markup.html.form.upload.FileUpload;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
@ -24,7 +23,7 @@ import io.onedev.server.manager.SettingManager;
|
||||
import io.onedev.server.persistence.annotation.Sessional;
|
||||
import io.onedev.server.util.facade.ProjectFacade;
|
||||
import io.onedev.server.util.facade.UserFacade;
|
||||
import io.onedev.utils.ExceptionUtils;
|
||||
import io.onedev.server.web.component.avatarupload.AvatarUploadField;
|
||||
import io.onedev.utils.FileUtils;
|
||||
import io.onedev.utils.LockUtils;
|
||||
import io.onedev.utils.StringUtils;
|
||||
@ -53,7 +52,7 @@ public class DefaultAvatarManager implements AvatarManager {
|
||||
} else {
|
||||
File avatarFile = getUploaded(user);
|
||||
if (avatarFile.exists()) {
|
||||
return AVATARS_BASE_URL + "uploaded/users/" + user.getId() + "?version=" + avatarFile.lastModified();
|
||||
return AVATARS_BASE_URL + "uploaded/users/" + user.getId() + ".jpg?version=" + avatarFile.lastModified();
|
||||
}
|
||||
|
||||
if (configManager.getSystemSetting().isGravatarEnabled())
|
||||
@ -71,7 +70,7 @@ public class DefaultAvatarManager implements AvatarManager {
|
||||
if (StringUtils.isBlank(secondaryName))
|
||||
secondaryName = primaryName;
|
||||
|
||||
File avatarFile = new File(Bootstrap.getSiteDir(), "avatars/generated/" + encoded);
|
||||
File avatarFile = new File(Bootstrap.getSiteDir(), "avatars/generated/" + encoded + ".png");
|
||||
if (!avatarFile.exists()) {
|
||||
Lock avatarLock = LockUtils.getLock("generated-avatar:" + encoded);
|
||||
avatarLock.lock();
|
||||
@ -87,7 +86,7 @@ public class DefaultAvatarManager implements AvatarManager {
|
||||
}
|
||||
}
|
||||
|
||||
return AVATARS_BASE_URL + "generated/" + encoded;
|
||||
return AVATARS_BASE_URL + "generated/" + encoded + ".png";
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,26 +116,18 @@ public class DefaultAvatarManager implements AvatarManager {
|
||||
|
||||
@Override
|
||||
public File getUploaded(UserFacade user) {
|
||||
return new File(Bootstrap.getSiteDir(), "avatars/uploaded/users/" + user.getId());
|
||||
return new File(Bootstrap.getSiteDir(), "avatars/uploaded/users/" + user.getId() + ".jpg");
|
||||
}
|
||||
|
||||
@Sessional
|
||||
@Override
|
||||
public void useAvatar(UserFacade user, FileUpload upload) {
|
||||
public void useAvatar(UserFacade user, String avatarData) {
|
||||
Lock avatarLock = LockUtils.getLock("uploaded-user-avatar:" + user.getId());
|
||||
avatarLock.lock();
|
||||
try {
|
||||
File avatarFile = getUploaded(user);
|
||||
if (upload != null) {
|
||||
FileUtils.createDir(avatarFile.getParentFile());
|
||||
try {
|
||||
upload.writeTo(avatarFile);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtils.unchecked(e);
|
||||
}
|
||||
} else {
|
||||
FileUtils.deleteFile(avatarFile);
|
||||
}
|
||||
FileUtils.createDir(avatarFile.getParentFile());
|
||||
AvatarUploadField.writeToFile(avatarFile, avatarData);
|
||||
} finally {
|
||||
avatarLock.unlock();
|
||||
}
|
||||
@ -146,27 +137,19 @@ public class DefaultAvatarManager implements AvatarManager {
|
||||
public String getAvatarUrl(ProjectFacade project) {
|
||||
File avatarFile = getUploaded(project);
|
||||
if (avatarFile.exists())
|
||||
return AVATARS_BASE_URL + "uploaded/projects/" + project.getId() + "?version=" + avatarFile.lastModified();
|
||||
return AVATARS_BASE_URL + "uploaded/projects/" + project.getId() + ".jpg?version=" + avatarFile.lastModified();
|
||||
else
|
||||
return AVATARS_BASE_URL + "project.png";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useAvatar(ProjectFacade project, FileUpload upload) {
|
||||
public void useAvatar(ProjectFacade project, String avatarData) {
|
||||
Lock avatarLock = LockUtils.getLock("uploaded-project-avatar:" + project.getId());
|
||||
avatarLock.lock();
|
||||
try {
|
||||
File avatarFile = getUploaded(project);
|
||||
if (upload != null) {
|
||||
FileUtils.createDir(avatarFile.getParentFile());
|
||||
try {
|
||||
upload.writeTo(avatarFile);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtils.unchecked(e);
|
||||
}
|
||||
} else {
|
||||
FileUtils.deleteFile(avatarFile);
|
||||
}
|
||||
FileUtils.createDir(avatarFile.getParentFile());
|
||||
AvatarUploadField.writeToFile(avatarFile, avatarData);
|
||||
} finally {
|
||||
avatarLock.unlock();
|
||||
}
|
||||
@ -174,7 +157,7 @@ public class DefaultAvatarManager implements AvatarManager {
|
||||
|
||||
@Override
|
||||
public File getUploaded(ProjectFacade project) {
|
||||
return new File(Bootstrap.getSiteDir(), "avatars/uploaded/projects/" + project.getId());
|
||||
return new File(Bootstrap.getSiteDir(), "avatars/uploaded/projects/" + project.getId() + ".jpg");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 13 KiB |
Loading…
x
Reference in New Issue
Block a user