Skip to content

Commit 1fdf560

Browse files
kolaentelunny
authored andcommitted
Added user language setting (#3875)
* Added user language setting * Added translation string for setting * Fixed import order + typo * improved checking if the user has a language saved in the db * The current saved language is now set a default inside the dropdown * fmt * When a user signs in and doesn't have a language saved, the current browser language is saved * updated gitea-sdk * Merge branch 'master' of https://github.com/go-gitea/gitea into save-user-language # Conflicts: # models/migrations/migrations.go # models/migrations/v62.go * Made tests work again * trigger CI * trigger CI * fmt * re-trigger that FUCKING CI SO IT REALLY PICKS UP THE LATEST COMMIT ISTEAD OF PREDENDING TO DO SO * re-trigger that FUCKING CI SO IT REALLY PICKS UP THE LATEST COMMIT ISTEAD OF PREDENDING TO DO SO * When loggin in, only the language col gets updated instead of everything
1 parent 795dcc8 commit 1fdf560

File tree

13 files changed

+81
-10
lines changed

13 files changed

+81
-10
lines changed

integrations/user_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ func TestRenameUsername(t *testing.T) {
2727

2828
session := loginUser(t, "user2")
2929
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
30-
"_csrf": GetCSRF(t, session, "/user/settings"),
31-
"name": "newUsername",
32-
"email": "[email protected]",
30+
"_csrf": GetCSRF(t, session, "/user/settings"),
31+
"name": "newUsername",
32+
"email": "[email protected]",
33+
"language": "en-us",
3334
})
3435
session.MakeRequest(t, req, http.StatusFound)
3536

@@ -81,9 +82,10 @@ func TestRenameReservedUsername(t *testing.T) {
8182
for _, reservedUsername := range reservedUsernames {
8283
t.Logf("Testing username %s", reservedUsername)
8384
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
84-
"_csrf": GetCSRF(t, session, "/user/settings"),
85-
"name": reservedUsername,
86-
"email": "[email protected]",
85+
"_csrf": GetCSRF(t, session, "/user/settings"),
86+
"name": reservedUsername,
87+
"email": "[email protected]",
88+
"language": "en-us",
8789
})
8890
resp := session.MakeRequest(t, req, http.StatusFound)
8991

integrations/xss_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func TestXSSUserFullName(t *testing.T) {
2424
"name": user.Name,
2525
"full_name": fullName,
2626
"email": user.Email,
27+
"language": "en-us",
2728
})
2829
session.MakeRequest(t, req, http.StatusFound)
2930

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ var migrations = []Migration{
178178
NewMigration("add size column for attachments", addSizeToAttachment),
179179
// v62 -> v63
180180
NewMigration("add last used passcode column for TOTP", addLastUsedPasscodeTOTP),
181+
// v63 -> v64
182+
NewMigration("add language column for user setting", addLanguageSetting),
181183
}
182184

183185
// Migrate database to current version

models/migrations/v63.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2018 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"fmt"
9+
10+
"github.com/go-xorm/xorm"
11+
)
12+
13+
func addLanguageSetting(x *xorm.Engine) error {
14+
type User struct {
15+
Language string `xorm:"VARCHAR(5)"`
16+
}
17+
18+
if err := x.Sync2(new(User)); err != nil {
19+
return fmt.Errorf("Sync2: %v", err)
20+
}
21+
22+
return nil
23+
}

models/user.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ type User struct {
9494
Website string
9595
Rands string `xorm:"VARCHAR(10)"`
9696
Salt string `xorm:"VARCHAR(10)"`
97+
Language string `xorm:"VARCHAR(5)"`
9798

9899
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
99100
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
@@ -185,6 +186,7 @@ func (u *User) APIFormat() *api.User {
185186
FullName: u.FullName,
186187
Email: u.getEmail(),
187188
AvatarURL: u.AvatarLink(),
189+
Language: u.Language,
188190
}
189191
}
190192

modules/auth/user_form.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ type UpdateProfileForm struct {
109109
KeepEmailPrivate bool
110110
Website string `binding:"ValidUrl;MaxSize(255)"`
111111
Location string `binding:"MaxSize(50)"`
112+
Language string `binding:"Size(5)"`
112113
}
113114

114115
// Validate validates the fields

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ change_username = Your username has been changed.
331331
change_username_prompt = Note: username changes also change your account URL.
332332
continue = Continue
333333
cancel = Cancel
334+
language = Language
334335
335336
lookup_avatar_by_mail = Look Up Avatar by Email Address
336337
federated_avatar_lookup = Federated Avatar Lookup

public/swagger.v1.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7318,6 +7318,11 @@
73187318
"format": "int64",
73197319
"x-go-name": "ID"
73207320
},
7321+
"language": {
7322+
"description": "User locale",
7323+
"type": "string",
7324+
"x-go-name": "Language"
7325+
},
73217326
"login": {
73227327
"description": "the user's username",
73237328
"type": "string",

routers/user/auth.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,18 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
339339
ctx.Session.Set("uid", u.ID)
340340
ctx.Session.Set("uname", u.Name)
341341

342+
// Language setting of the user overwrites the one previously set
343+
// If the user does not have a locale set, we save the current one.
344+
if len(u.Language) == 0 {
345+
u.Language = ctx.Locale.Language()
346+
if err := models.UpdateUserCols(u, "language"); err != nil {
347+
log.Error(4, fmt.Sprintf("Error updating user language [user: %d, locale: %s]", u.ID, u.Language))
348+
return
349+
}
350+
}
351+
352+
ctx.SetCookie("lang", u.Language, nil, setting.AppSubURL)
353+
342354
// Clear whatever CSRF has right now, force to generate a new one
343355
ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL)
344356

@@ -704,6 +716,7 @@ func SignOut(ctx *context.Context) {
704716
ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubURL)
705717
ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubURL)
706718
ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL)
719+
ctx.SetCookie("lang", "", -1, setting.AppSubURL) // Setting the lang cookie will trigger the middleware to reset the language ot previous state.
707720
ctx.Redirect(setting.AppSubURL + "/")
708721
}
709722

routers/user/setting.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313

1414
"github.com/Unknwon/com"
15+
"github.com/Unknwon/i18n"
1516
"github.com/pquerna/otp"
1617
"github.com/pquerna/otp/totp"
1718

@@ -105,6 +106,7 @@ func SettingsPost(ctx *context.Context, form auth.UpdateProfileForm) {
105106
ctx.User.KeepEmailPrivate = form.KeepEmailPrivate
106107
ctx.User.Website = form.Website
107108
ctx.User.Location = form.Location
109+
ctx.User.Language = form.Language
108110
if err := models.UpdateUserSetting(ctx.User); err != nil {
109111
if _, ok := err.(models.ErrEmailAlreadyUsed); ok {
110112
ctx.Flash.Error(ctx.Tr("form.email_been_used"))
@@ -115,8 +117,11 @@ func SettingsPost(ctx *context.Context, form auth.UpdateProfileForm) {
115117
return
116118
}
117119

120+
// Update the language to the one we just set
121+
ctx.SetCookie("lang", ctx.User.Language, nil, setting.AppSubURL)
122+
118123
log.Trace("User settings updated: %s", ctx.User.Name)
119-
ctx.Flash.Success(ctx.Tr("settings.update_profile_success"))
124+
ctx.Flash.Success(i18n.Tr(ctx.User.Language, "settings.update_profile_success"))
120125
ctx.Redirect(setting.AppSubURL + "/user/settings")
121126
}
122127

templates/user/settings/profile.tmpl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@
4040
<input id="location" name="location" value="{{.SignedUser.Location}}">
4141
</div>
4242

43+
<div class="field">
44+
<label for="language">{{.i18n.Tr "settings.language"}}</label>
45+
<div class="ui language selection dropdown" id="language">
46+
<input name="language" type="hidden">
47+
<i class="dropdown icon"></i>
48+
<div class="text">{{range .AllLangs}}{{if eq $.SignedUser.Language .Lang}}{{.Name}}{{end}}{{end}}</div>
49+
<div class="menu">
50+
{{range .AllLangs}}
51+
<div class="item{{if eq $.SignedUser.Language .Lang}} active selected{{end}}" data-value="{{.Lang}}">{{.Name}}</div>
52+
{{end}}
53+
</div>
54+
</div>
55+
</div>
56+
4357
<div class="field">
4458
<button class="ui green button">{{$.i18n.Tr "settings.update_profile"}}</button>
4559
</div>

vendor/code.gitea.io/sdk/gitea/user.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/vendor.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
"revisionTime": "2018-04-21T01:08:19Z"
1010
},
1111
{
12-
"checksumSHA1": "xXzi8Xx7HA3M0z3lR/1wr1Vz1fc=",
12+
"checksumSHA1": "WMD6+Qh2+5hd9uiq910pF/Ihylw=",
1313
"path": "code.gitea.io/sdk/gitea",
14-
"revision": "142acef5ce79f78585afcce31748af46c72a3dea",
15-
"revisionTime": "2018-04-17T00:54:29Z"
14+
"revision": "1c8d12f79a51605ed91587aa6b86cf38fc0f987f",
15+
"revisionTime": "2018-05-01T11:15:19Z"
1616
},
1717
{
1818
"checksumSHA1": "bOODD4Gbw3GfcuQPU2dI40crxxk=",

0 commit comments

Comments
 (0)