mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-22 21:54:00 +01:00
parent
2a931937a8
commit
a2f13eae55
10 changed files with 79 additions and 46 deletions
|
@ -217,6 +217,7 @@ func runWeb(ctx *cli.Context) {
|
||||||
m.Get("", user.Settings)
|
m.Get("", user.Settings)
|
||||||
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
|
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
|
||||||
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), user.SettingsAvatar)
|
m.Post("/avatar", binding.MultipartForm(auth.UploadAvatarForm{}), user.SettingsAvatar)
|
||||||
|
m.Post("/avatar/delete", user.SettingsDeleteAvatar)
|
||||||
m.Combo("/email").Get(user.SettingsEmails).
|
m.Combo("/email").Get(user.SettingsEmails).
|
||||||
Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
|
Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
|
||||||
m.Post("/email/delete", user.DeleteEmail)
|
m.Post("/email/delete", user.DeleteEmail)
|
||||||
|
|
|
@ -264,11 +264,10 @@ continue = Continue
|
||||||
cancel = Cancel
|
cancel = Cancel
|
||||||
|
|
||||||
enable_custom_avatar = Enable Custom Avatar
|
enable_custom_avatar = Enable Custom Avatar
|
||||||
enable_custom_avatar_helper = Disable fetch from Gravatar
|
|
||||||
choose_new_avatar = Choose new avatar
|
choose_new_avatar = Choose new avatar
|
||||||
update_avatar = Update Avatar Setting
|
update_avatar = Update Avatar Setting
|
||||||
|
delete_current_avatar = Delete Current Avatar
|
||||||
uploaded_avatar_not_a_image = Uploaded file is not a image.
|
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.
|
update_avatar_success = Your avatar setting has been updated successfully.
|
||||||
|
|
||||||
change_password = Change Password
|
change_password = Change Password
|
||||||
|
|
2
gogs.go
2
gogs.go
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/gogits/gogs/modules/setting"
|
"github.com/gogits/gogs/modules/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APP_VER = "0.8.57.0304"
|
const APP_VER = "0.8.57.0305"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
|
|
|
@ -617,7 +617,7 @@ func ChangeUserName(u *User, newUserName string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUser(e Engine, u *User) error {
|
func updateUser(e Engine, u *User) error {
|
||||||
// Organization does not need e-mail.
|
// Organization does not need email
|
||||||
if !u.IsOrganization() {
|
if !u.IsOrganization() {
|
||||||
u.Email = strings.ToLower(u.Email)
|
u.Email = strings.ToLower(u.Email)
|
||||||
has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
|
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)
|
u.LowerName = strings.ToLower(u.Name)
|
||||||
|
u.Location = base.TruncateString(u.Location, 255)
|
||||||
if len(u.Location) > 255 {
|
u.Website = base.TruncateString(u.Website, 255)
|
||||||
u.Location = u.Location[:255]
|
u.Description = base.TruncateString(u.Description, 255)
|
||||||
}
|
|
||||||
if len(u.Website) > 255 {
|
|
||||||
u.Website = u.Website[:255]
|
|
||||||
}
|
|
||||||
if len(u.Description) > 255 {
|
|
||||||
u.Description = u.Description[:255]
|
|
||||||
}
|
|
||||||
|
|
||||||
u.FullName = markdown.Sanitizer.Sanitize(u.FullName)
|
u.FullName = markdown.Sanitizer.Sanitize(u.FullName)
|
||||||
_, err := e.Id(u.Id).AllCols().Update(u)
|
_, err := e.Id(u.Id).AllCols().Update(u)
|
||||||
|
|
|
@ -464,6 +464,15 @@ func EllipsisString(str string, length int) string {
|
||||||
return str[:length-3] + "..."
|
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.
|
// StringsToInt64s converts a slice of string to a slice of int64.
|
||||||
func StringsToInt64s(strs []string) []int64 {
|
func StringsToInt64s(strs []string) []int64 {
|
||||||
ints := make([]int64, len(strs))
|
ints := make([]int64, len(strs))
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -18,7 +18,7 @@ function initCommentPreviewTab($form) {
|
||||||
var $preview_tab = $form.find('.tab.segment[data-tab="' + $tab_menu.data('preview') + '"]');
|
var $preview_tab = $form.find('.tab.segment[data-tab="' + $tab_menu.data('preview') + '"]');
|
||||||
$preview_tab.html(data);
|
$preview_tab.html(data);
|
||||||
emojify.run($preview_tab[0]);
|
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);
|
hljs.highlightBlock(block);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -322,8 +322,7 @@ function initRepository() {
|
||||||
};
|
};
|
||||||
$('#edit-title').click(editTitleToggle);
|
$('#edit-title').click(editTitleToggle);
|
||||||
$('#cancel-edit-title').click(editTitleToggle);
|
$('#cancel-edit-title').click(editTitleToggle);
|
||||||
$('#save-edit-title').click(editTitleToggle).
|
$('#save-edit-title').click(editTitleToggle).click(function () {
|
||||||
click(function () {
|
|
||||||
if ($edit_input.val().length == 0 ||
|
if ($edit_input.val().length == 0 ||
|
||||||
$edit_input.val() == $issue_title.text()) {
|
$edit_input.val() == $issue_title.text()) {
|
||||||
$edit_input.val($issue_title.text());
|
$edit_input.val($issue_title.text());
|
||||||
|
@ -385,7 +384,7 @@ function initRepository() {
|
||||||
} else {
|
} else {
|
||||||
$render_content.html(data.content);
|
$render_content.html(data.content);
|
||||||
emojify.run($render_content[0]);
|
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);
|
hljs.highlightBlock(block);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -521,10 +520,8 @@ function initOrganization() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initUser() {
|
function initUserSettings() {
|
||||||
if ($('.user').length == 0) {
|
console.log('initUserSettings');
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
if ($('.user.settings.profile').length > 0) {
|
if ($('.user.settings.profile').length > 0) {
|
||||||
|
@ -796,10 +793,7 @@ $(document).ready(function () {
|
||||||
|
|
||||||
// Show exact time
|
// Show exact time
|
||||||
$('.time-since').each(function () {
|
$('.time-since').each(function () {
|
||||||
$(this).addClass('poping up').
|
$(this).addClass('poping up').attr('data-content', $(this).attr('title')).attr('data-variation', 'inverted tiny').attr('title', '');
|
||||||
attr('data-content', $(this).attr('title')).
|
|
||||||
attr('data-variation', 'inverted tiny').
|
|
||||||
attr('title', '');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Semantic UI modules.
|
// Semantic UI modules.
|
||||||
|
@ -879,8 +873,8 @@ $(document).ready(function () {
|
||||||
ignore_emoticons: true
|
ignore_emoticons: true
|
||||||
});
|
});
|
||||||
var hasEmoji = document.getElementsByClassName('has-emoji');
|
var hasEmoji = document.getElementsByClassName('has-emoji');
|
||||||
for (var i = 0; i < hasEmoji.length; i++) {
|
for (var i = 0; i < hasEmoji.length; i++) {
|
||||||
emojify.run(hasEmoji[i]);
|
emojify.run(hasEmoji[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clipboard JS
|
// Clipboard JS
|
||||||
|
@ -928,6 +922,14 @@ $(document).ready(function () {
|
||||||
$('.show-modal.button').click(function () {
|
$('.show-modal.button').click(function () {
|
||||||
$($(this).data('modal')).modal('show');
|
$($(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.
|
// Set anchor.
|
||||||
$('.markdown').each(function () {
|
$('.markdown').each(function () {
|
||||||
|
@ -953,15 +955,25 @@ $(document).ready(function () {
|
||||||
searchUsers();
|
searchUsers();
|
||||||
searchRepositories();
|
searchRepositories();
|
||||||
|
|
||||||
|
|
||||||
initCommentForm();
|
initCommentForm();
|
||||||
initInstall();
|
initInstall();
|
||||||
initRepository();
|
initRepository();
|
||||||
initWiki();
|
initWiki();
|
||||||
initOrganization();
|
initOrganization();
|
||||||
initUser();
|
|
||||||
initWebhook();
|
initWebhook();
|
||||||
initAdmin();
|
initAdmin();
|
||||||
|
|
||||||
|
var routes = {
|
||||||
|
'div.user.settings': initUserSettings
|
||||||
|
};
|
||||||
|
|
||||||
|
var selector;
|
||||||
|
for (selector in routes) {
|
||||||
|
if ($(selector).length > 0) {
|
||||||
|
routes[selector]();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(window).load(function () {
|
$(window).load(function () {
|
||||||
|
@ -1053,7 +1065,8 @@ $(window).load(function () {
|
||||||
case 'ssh':
|
case 'ssh':
|
||||||
if ($('#repo-clone-ssh').click().length === 0) {
|
if ($('#repo-clone-ssh').click().length === 0) {
|
||||||
$('#repo-clone-https').click();
|
$('#repo-clone-https').click();
|
||||||
};
|
}
|
||||||
|
;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$('#repo-clone-https').click();
|
$('#repo-clone-https').click();
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Unknwon/com"
|
"github.com/Unknwon/com"
|
||||||
|
@ -39,12 +40,13 @@ func Settings(ctx *middleware.Context) {
|
||||||
ctx.HTML(200, SETTINGS_PROFILE)
|
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() {
|
if len(newName) == 0 || !ctx.User.IsLocal() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if user name has been changed.
|
// Check if user name has been changed
|
||||||
if ctx.User.LowerName != strings.ToLower(newName) {
|
if ctx.User.LowerName != strings.ToLower(newName) {
|
||||||
if err := models.ChangeUserName(ctx.User, newName); err != nil {
|
if err := models.ChangeUserName(ctx.User, newName); err != nil {
|
||||||
switch {
|
switch {
|
||||||
|
@ -67,7 +69,8 @@ func handlerUsernameChange(ctx *middleware.Context, newName string) {
|
||||||
}
|
}
|
||||||
log.Trace("User name changed: %s -> %s", ctx.User.Name, newName)
|
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.Name = newName
|
||||||
ctx.User.LowerName = strings.ToLower(newName)
|
ctx.User.LowerName = strings.ToLower(newName)
|
||||||
}
|
}
|
||||||
|
@ -81,7 +84,7 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
handlerUsernameChange(ctx, form.Name)
|
handleUsernameChange(ctx, form.Name)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -98,7 +101,8 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateProfileForm) {
|
||||||
ctx.Handle(500, "UpdateUser", err)
|
ctx.Handle(500, "UpdateUser", err)
|
||||||
return
|
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.Flash.Success(ctx.Tr("settings.update_profile_success"))
|
||||||
ctx.Redirect(setting.AppSubUrl + "/user/settings")
|
ctx.Redirect(setting.AppSubUrl + "/user/settings")
|
||||||
}
|
}
|
||||||
|
@ -112,10 +116,11 @@ func UpdateAvatarSetting(ctx *middleware.Context, form auth.UploadAvatarForm, ct
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Avatar.Open: %v", err)
|
return fmt.Errorf("Avatar.Open: %v", err)
|
||||||
}
|
}
|
||||||
|
defer fr.Close()
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(fr)
|
data, err := ioutil.ReadAll(fr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ReadAll: %v", err)
|
return fmt.Errorf("ioutil.ReadAll: %v", err)
|
||||||
}
|
}
|
||||||
if _, ok := base.IsImageFile(data); !ok {
|
if _, ok := base.IsImageFile(data); !ok {
|
||||||
return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image"))
|
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)
|
return fmt.Errorf("UploadAvatar: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// In case no avatar at all.
|
// No avatar is uploaded but setting has been changed to enable,
|
||||||
if form.Enable && !com.IsFile(ctx.User.CustomAvatarPath()) {
|
// generate a random one when needed.
|
||||||
return errors.New(ctx.Tr("settings.no_custom_avatar_available"))
|
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")
|
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) {
|
func SettingsPassword(ctx *middleware.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("settings")
|
ctx.Data["Title"] = ctx.Tr("settings")
|
||||||
ctx.Data["PageIsSettingsPassword"] = true
|
ctx.Data["PageIsSettingsPassword"] = true
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.8.57.0304
|
0.8.57.0305
|
|
@ -52,10 +52,9 @@
|
||||||
<form class="ui form" action="{{.Link}}/avatar" method="post" enctype="multipart/form-data">
|
<form class="ui form" action="{{.Link}}/avatar" method="post" enctype="multipart/form-data">
|
||||||
{{.CsrfTokenHtml}}
|
{{.CsrfTokenHtml}}
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label>{{.i18n.Tr "settings.enable_custom_avatar"}}</label>
|
|
||||||
<div class="ui checkbox">
|
<div class="ui checkbox">
|
||||||
<input name="enable" type="checkbox" {{if .SignedUser.UseCustomAvatar}}checked{{end}}>
|
<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>
|
</div>
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
|
@ -65,6 +64,7 @@
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<button class="ui green button">{{$.i18n.Tr "settings.update_avatar"}}</button>
|
<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>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue