Commit a2f13eae authored by Unknwon's avatar Unknwon
Browse files

#1157 some avatar setting changes

- Allow to delete current avatar
parent 2a931937
main release/v1.10 release/v1.11 release/v1.12 release/v1.13 release/v1.14 release/v1.15 release/v1.16 release/v1.17 release/v1.18 release/v1.8 release/v1.9 v1.19.0-dev v1.18.1 v1.18.0 v1.18.0-rc1 v1.18.0-rc0 v1.18.0-dev v1.17.4 v1.17.3 v1.17.2 v1.17.1 v1.17.0 v1.17.0-rc2 v1.17.0-rc1 v1.17.0-dev v1.16.9 v1.16.8 v1.16.7 v1.16.6 v1.16.5 v1.16.4 v1.16.3 v1.16.2 v1.16.1 v1.16.0 v1.16.0-rc1 v1.16.0-dev v1.15.11 v1.15.10 v1.15.9 v1.15.8 v1.15.7 v1.15.6 v1.15.5 v1.15.4 v1.15.3 v1.15.2 v1.15.1 v1.15.0 v1.15.0-rc3 v1.15.0-rc2 v1.15.0-rc1 v1.15.0-dev v1.14.7 v1.14.6 v1.14.5 v1.14.4 v1.14.3 v1.14.2 v1.14.1 v1.14.0 v1.14.0-rc2 v1.14.0-rc1 v1.14.0-dev v1.13.7 v1.13.6 v1.13.5 v1.13.4 v1.13.3 v1.13.2 v1.13.1 v1.13.0 v1.13.0-rc2 v1.13.0-rc1 v1.13.0-dev v1.12.6 v1.12.5 v1.12.4 v1.12.3 v1.12.2 v1.12.1 v1.12.0 v1.12.0-rc2 v1.12.0-rc1 v1.12.0-dev v1.11.8 v1.11.7 v1.11.6 v1.11.5 v1.11.4 v1.11.3 v1.11.2 v1.11.1 v1.11.0 v1.11.0-rc2 v1.11.0-rc1 v1.11.0-dev v1.10.6 v1.10.5 v1.10.4 v1.10.3 v1.10.2 v1.10.1 v1.10.0 v1.10.0-rc2 v1.10.0-rc1 v1.10.0-dev v1.9.6 v1.9.5 v1.9.4 v1.9.3 v1.9.2 v1.9.1 v1.9.0 v1.9.0-rc2 v1.9.0-rc1 v1.9.0-dev v1.8.3 v1.8.2 v1.8.1 v1.8.0 v1.8.0-rc3 v1.8.0-rc2 v1.8.0-rc1 v1.7.6 v1.7.5 v1.7.4 v1.7.3 v1.7.2 v1.7.1 v1.7.0 v1.7.0-rc3 v1.7.0-rc2 v1.7.0-rc1 v1.7.0-dev v1.6.4 v1.6.3 v1.6.2 v1.6.1 v1.6.0 v1.6.0-rc2 v1.6.0-rc1 v1.6.0-dev v1.5.3 v1.5.2 v1.5.1 v1.5.0 v1.5.0-rc2 v1.5.0-rc1 v1.5.0-dev v1.4.3 v1.4.2 v1.4.1 v1.4.0 v1.4.0-rc3 v1.4.0-rc2 v1.4.0-rc1 v1.3.3 v1.3.2 v1.3.1 v1.3.0 v1.3.0-rc2 v1.3.0-rc1 v1.2.3 v1.2.2 v1.2.1 v1.2.0 v1.2.0-rc3 v1.2.0-rc2 v1.2.0-rc1 v1.1.4 v1.1.3 v1.1.2 v1.1.1 v1.1.0 v1.0.2 v1.0.1 v1.0.0 v0.9.99
No related merge requests found
Showing with 79 additions and 46 deletions
+79 -46
......@@ -217,6 +217,7 @@ func runWeb(ctx *cli.Context) {
m.Get("", user.Settings)
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), user.SettingsAvatar)
m.Post("/avatar/delete", user.SettingsDeleteAvatar)
m.Combo("/email").Get(user.SettingsEmails).
Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
m.Post("/email/delete", user.DeleteEmail)
......
......@@ -264,11 +264,10 @@ continue = Continue
cancel = Cancel
enable_custom_avatar = Enable Custom Avatar
enable_custom_avatar_helper = Disable fetch from Gravatar
choose_new_avatar = Choose new avatar
update_avatar = Update Avatar Setting
delete_current_avatar = Delete Current Avatar
uploaded_avatar_not_a_image = Uploaded file is not a image.
no_custom_avatar_available = No custom avatar available, cannot enable it.
update_avatar_success = Your avatar setting has been updated successfully.
change_password = Change Password
......
......@@ -17,7 +17,7 @@ import (
"github.com/gogits/gogs/modules/setting"
)
const APP_VER = "0.8.57.0304"
const APP_VER = "0.8.57.0305"
func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
......
......@@ -617,7 +617,7 @@ func ChangeUserName(u *User, newUserName string) (err error) {
}
func updateUser(e Engine, u *User) error {
// Organization does not need e-mail.
// Organization does not need email
if !u.IsOrganization() {
u.Email = strings.ToLower(u.Email)
has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
......@@ -634,16 +634,9 @@ func updateUser(e Engine, u *User) error {
}
u.LowerName = strings.ToLower(u.Name)
if len(u.Location) > 255 {
u.Location = u.Location[:255]
}
if len(u.Website) > 255 {
u.Website = u.Website[:255]
}
if len(u.Description) > 255 {
u.Description = u.Description[:255]
}
u.Location = base.TruncateString(u.Location, 255)
u.Website = base.TruncateString(u.Website, 255)
u.Description = base.TruncateString(u.Description, 255)
u.FullName = markdown.Sanitizer.Sanitize(u.FullName)
_, err := e.Id(u.Id).AllCols().Update(u)
......
......@@ -464,6 +464,15 @@ func EllipsisString(str string, length int) string {
return str[:length-3] + "..."
}
// TruncateString returns a truncated string with given limit,
// it returns input string if length is not reached limit.
func TruncateString(str string, limit int) string {
if len(str) < limit {
return str
}
return str[:limit]
}
// StringsToInt64s converts a slice of string to a slice of int64.
func StringsToInt64s(strs []string) []int64 {
ints := make([]int64, len(strs))
......
This diff is collapsed.
......@@ -18,7 +18,7 @@ function initCommentPreviewTab($form) {
var $preview_tab = $form.find('.tab.segment[data-tab="' + $tab_menu.data('preview') + '"]');
$preview_tab.html(data);
emojify.run($preview_tab[0]);
$('pre code', $preview_tab[0]).each(function(i, block) {
$('pre code', $preview_tab[0]).each(function (i, block) {
hljs.highlightBlock(block);
});
}
......@@ -322,8 +322,7 @@ function initRepository() {
};
$('#edit-title').click(editTitleToggle);
$('#cancel-edit-title').click(editTitleToggle);
$('#save-edit-title').click(editTitleToggle).
click(function () {
$('#save-edit-title').click(editTitleToggle).click(function () {
if ($edit_input.val().length == 0 ||
$edit_input.val() == $issue_title.text()) {
$edit_input.val($issue_title.text());
......@@ -385,7 +384,7 @@ function initRepository() {
} else {
$render_content.html(data.content);
emojify.run($render_content[0]);
$('pre code', $render_content[0]).each(function(i, block) {
$('pre code', $render_content[0]).each(function (i, block) {
hljs.highlightBlock(block);
});
}
......@@ -521,10 +520,8 @@ function initOrganization() {
}
}
function initUser() {
if ($('.user').length == 0) {
return;
}
function initUserSettings() {
console.log('initUserSettings');
// Options
if ($('.user.settings.profile').length > 0) {
......@@ -796,10 +793,7 @@ $(document).ready(function () {
// Show exact time
$('.time-since').each(function () {
$(this).addClass('poping up').
attr('data-content', $(this).attr('title')).
attr('data-variation', 'inverted tiny').
attr('title', '');
$(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', '');
});
// Semantic UI modules.
......@@ -879,8 +873,8 @@ $(document).ready(function () {
ignore_emoticons: true
});
var hasEmoji = document.getElementsByClassName('has-emoji');
for (var i = 0; i < hasEmoji.length; i++) {
emojify.run(hasEmoji[i]);
for (var i = 0; i < hasEmoji.length; i++) {
emojify.run(hasEmoji[i]);
}
// Clipboard JS
......@@ -928,6 +922,14 @@ $(document).ready(function () {
$('.show-modal.button').click(function () {
$($(this).data('modal')).modal('show');
});
$('.delete-post.button').click(function(){
var $this = $(this);
$.post($this.data('request-url'),{
"_csrf": csrf
}).done(function(){
window.location.href = $this.data('done-url');
});
});
// Set anchor.
$('.markdown').each(function () {
......@@ -953,15 +955,25 @@ $(document).ready(function () {
searchUsers();
searchRepositories();
initCommentForm();
initInstall();
initRepository();
initWiki();
initOrganization();
initUser();
initWebhook();
initAdmin();
var routes = {
'div.user.settings': initUserSettings
};
var selector;
for (selector in routes) {
if ($(selector).length > 0) {
routes[selector]();
break;
}
}
});
$(window).load(function () {
......@@ -1053,11 +1065,12 @@ $(window).load(function () {
case 'ssh':
if ($('#repo-clone-ssh').click().length === 0) {
$('#repo-clone-https').click();
};
}
;
break;
default:
$('#repo-clone-https').click();
break;
}
}
});
});
\ No newline at end of file
......@@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/Unknwon/com"
......@@ -39,12 +40,13 @@ func Settings(ctx *middleware.Context) {
ctx.HTML(200, SETTINGS_PROFILE)
}
func handlerUsernameChange(ctx *middleware.Context, newName string) {
func handleUsernameChange(ctx *middleware.Context, newName string) {
// Non-local users are not allowed to change their username.
if len(newName) == 0 || !ctx.User.IsLocal() {
return
}
// Check if user name has been changed.
// Check if user name has been changed
if ctx.User.LowerName != strings.ToLower(newName) {
if err := models.ChangeUserName(ctx.User, newName); err != nil {
switch {
......@@ -67,7 +69,8 @@ func handlerUsernameChange(ctx *middleware.Context, newName string) {
}
log.Trace("User name changed: %s -> %s", ctx.User.Name, newName)
}
// In case it's just a case change.
// In case it's just a case change
ctx.User.Name = newName
ctx.User.LowerName = strings.ToLower(newName)
}
......@@ -81,7 +84,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
return
}
handlerUsernameChange(ctx, form.Name)
handleUsernameChange(ctx, form.Name)
if ctx.Written() {
return
}
......@@ -98,7 +101,8 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
ctx.Handle(500, "UpdateUser", err)
return
}
log.Trace("User setting updated: %s", ctx.User.Name)
log.Trace("User settings updated: %s", ctx.User.Name)
ctx.Flash.Success(ctx.Tr("settings.update_profile_success"))
ctx.Redirect(setting.AppSubUrl + "/user/settings")
}
......@@ -112,10 +116,11 @@ func UpdateAvatarSetting(ctx *middleware.Context, form auth.UploadAvatarForm, ct
if err != nil {
return fmt.Errorf("Avatar.Open: %v", err)
}
defer fr.Close()
data, err := ioutil.ReadAll(fr)
if err != nil {
return fmt.Errorf("ReadAll: %v", err)
return fmt.Errorf("ioutil.ReadAll: %v", err)
}
if _, ok := base.IsImageFile(data); !ok {
return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image"))
......@@ -124,9 +129,12 @@ func UpdateAvatarSetting(ctx *middleware.Context, form auth.UploadAvatarForm, ct
return fmt.Errorf("UploadAvatar: %v", err)
}
} else {
// In case no avatar at all.
if form.Enable && !com.IsFile(ctx.User.CustomAvatarPath()) {
return errors.New(ctx.Tr("settings.no_custom_avatar_available"))
// No avatar is uploaded but setting has been changed to enable,
// generate a random one when needed.
if form.Enable && !com.IsFile(ctxUser.CustomAvatarPath()) {
if err := ctxUser.GenerateRandomAvatar(); err != nil {
log.Error(4, "GenerateRandomAvatar[%d]: %v", ctxUser.Id, err)
}
}
}
......@@ -147,6 +155,16 @@ func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) {
ctx.Redirect(setting.AppSubUrl + "/user/settings")
}
func SettingsDeleteAvatar(ctx *middleware.Context) {
os.Remove(ctx.User.CustomAvatarPath())
ctx.User.UseCustomAvatar = false
if err := models.UpdateUser(ctx.User); err != nil {
ctx.Flash.Error(fmt.Sprintf("UpdateUser: %v", err))
}
ctx.Redirect(setting.AppSubUrl + "/user/settings")
}
func SettingsPassword(ctx *middleware.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsSettingsPassword"] = true
......
0.8.57.0304
\ No newline at end of file
0.8.57.0305
\ No newline at end of file
......@@ -52,10 +52,9 @@
<form class="ui form" action="{{.Link}}/avatar" method="post" enctype="multipart/form-data">
{{.CsrfTokenHtml}}
<div class="inline field">
<label>{{.i18n.Tr "settings.enable_custom_avatar"}}</label>
<div class="ui checkbox">
<input name="enable" type="checkbox" {{if .SignedUser.UseCustomAvatar}}checked{{end}}>
<label>{{.i18n.Tr "settings.enable_custom_avatar_helper"}}</label>
<label>{{.i18n.Tr "settings.enable_custom_avatar"}}</label>
</div>
</div>
<div class="inline field">
......@@ -65,6 +64,7 @@
<div class="field">
<button class="ui green button">{{$.i18n.Tr "settings.update_avatar"}}</button>
<a class="ui red button delete-post" data-request-url="{{.Link}}/avatar/delete" data-done-url="{{.Link}}">{{$.i18n.Tr "settings.delete_current_avatar"}}</a>
</div>
</form>
</div>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment