diff options
-rw-r--r-- | custom/conf/app.example.ini | 9 | ||||
-rw-r--r-- | docs/content/administration/config-cheat-sheet.en-us.md | 1 | ||||
-rw-r--r-- | modules/setting/service.go | 2 | ||||
-rw-r--r-- | options/locale/locale_en-US.ini | 2 | ||||
-rw-r--r-- | routers/web/user/profile.go | 1 | ||||
-rw-r--r-- | templates/shared/user/profile_big_avatar.tmpl | 19 | ||||
-rw-r--r-- | templates/user/settings/profile.tmpl | 2 | ||||
-rw-r--r-- | tests/integration/user_test.go | 21 | ||||
-rw-r--r-- | web_src/css/user.css | 8 |
9 files changed, 54 insertions, 11 deletions
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index e5f72d436c..94c15a60d9 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -827,6 +827,15 @@ LEVEL = Info ;; Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting. ;ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true ;; +;; Default map service. No external API support has been included. A service has to allow +;; searching using URL parameters, the location will be appended to the URL as escaped query parameter. +;; Disabled by default, some example values are: +;; - OpenStreetMap: https://www.openstreetmap.org/search?query= +;; - Google Maps: https://www.google.com/maps/place/ +;; - MapQuest: https://www.mapquest.com/search/ +;; - Bing Maps: https://www.bing.com/maps?where1= +; USER_LOCATION_MAP_URL = +;; ;; Enable heatmap on users profiles. ;ENABLE_USER_HEATMAP = true ;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index f30e0e246a..30751bf071 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -648,6 +648,7 @@ And the following unique queues: - `DEFAULT_USER_IS_RESTRICTED`: **false**: Give new users restricted permissions by default - `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default. - `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access. +- `USER_LOCATION_MAP_URL`: **""**: A map service URL to show user's location on a map. The location will be appended to the URL as escaped query parameter. - `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles. - `ENABLE_TIMETRACKING`: **true**: Enable Timetracking feature. - `DEFAULT_ENABLE_TIMETRACKING`: **true**: Allow repositories to use timetracking by default. diff --git a/modules/setting/service.go b/modules/setting/service.go index 597fecee1d..595ea6528f 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -73,6 +73,7 @@ var Service = struct { AllowCrossRepositoryDependencies bool DefaultAllowOnlyContributorsToTrackTime bool NoReplyAddress string + UserLocationMapURL string EnableUserHeatmap bool AutoWatchNewRepos bool AutoWatchOnChanges bool @@ -185,6 +186,7 @@ func loadServiceFrom(rootCfg ConfigProvider) { Service.AllowCrossRepositoryDependencies = sec.Key("ALLOW_CROSS_REPOSITORY_DEPENDENCIES").MustBool(true) Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true) Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply." + Domain) + Service.UserLocationMapURL = sec.Key("USER_LOCATION_MAP_URL").String() Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true) Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true) Service.AutoWatchOnChanges = sec.Key("AUTO_WATCH_ON_CHANGES").MustBool(false) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index cf04830cbb..3256d2ba91 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -601,6 +601,7 @@ user_bio = Biography disabled_public_activity = This user has disabled the public visibility of the activity. email_visibility.limited = Your email address is visible to all authenticated users email_visibility.private = Your email address is only visible to you and administrators +show_on_map = Show this place on a map form.name_reserved = The username "%s" is reserved. form.name_pattern_not_allowed = The pattern "%s" is not allowed in a username. @@ -627,6 +628,7 @@ webauthn = Security Keys public_profile = Public Profile biography_placeholder = Tell us a little bit about yourself +location_placeholder = Share your approximate location with others profile_desc = Your email address will be used for notifications and other operations. password_username_disabled = Non-local users are not allowed to change their username. Please contact your site administrator for more details. full_name = Full Name diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 15a9197b98..7f6e41d30f 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -52,6 +52,7 @@ func userProfile(ctx *context.Context) { ctx.Data["Title"] = ctx.ContextUser.DisplayName() ctx.Data["PageIsUserProfile"] = true + ctx.Data["UserLocationMapURL"] = setting.Service.UserLocationMapURL // prepare heatmap data if setting.Service.EnableUserHeatmap { diff --git a/templates/shared/user/profile_big_avatar.tmpl b/templates/shared/user/profile_big_avatar.tmpl index 62b317cdd4..97afbb6580 100644 --- a/templates/shared/user/profile_big_avatar.tmpl +++ b/templates/shared/user/profile_big_avatar.tmpl @@ -24,19 +24,28 @@ <div class="extra content gt-word-break"> <ul> {{if .ContextUser.Location}} - <li>{{svg "octicon-location"}} {{.ContextUser.Location}}</li> + <li> + {{svg "octicon-location"}} + <span class="gt-f1">{{.ContextUser.Location}}</span> + {{if .UserLocationMapURL}} + {{/* We presume that the UserLocationMapURL is safe, as it is provided by the site administrator. */}} + <a href="{{.UserLocationMapURL | Safe}}{{.ContextUser.Location | QueryEscape}}" rel="nofollow noreferrer" data-tooltip-content="{{.locale.Tr "user.show_on_map"}}"> + {{svg "octicon-link-external"}} + </a> + {{end}} + </li> {{end}} {{if (eq .SignedUserID .ContextUser.ID)}} <li> {{svg "octicon-mail"}} - <a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a> + <a class="gt-f1" href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a> <a href="{{AppSubUrl}}/user/settings#keep-email-private"> {{if .ShowUserEmail}} - <i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}"> + <i data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}"> {{svg "octicon-unlock"}} </i> {{else}} - <i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}"> + <i data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}"> {{svg "octicon-lock"}} </i> {{end}} @@ -69,7 +78,7 @@ </li> {{end}} {{end}} - <li>{{svg "octicon-calendar"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</li> + <li>{{svg "octicon-calendar"}} <span>{{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</span></li> {{if and .Orgs .HasOrgsVisible}} <li> <ul class="user-orgs"> diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index 9f1f743f9c..e0240e391f 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -35,7 +35,7 @@ </div> <div class="field"> <label for="location">{{.locale.Tr "settings.location"}}</label> - <input id="location" name="location" value="{{.SignedUser.Location}}" maxlength="50"> + <input id="location" name="location" placeholder="{{.locale.Tr "settings.location_placeholder"}}" value="{{.SignedUser.Location}}" maxlength="50"> </div> <div class="divider"></div> diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index 3e4d967686..ddde415960 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -12,6 +12,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/translation" @@ -276,3 +277,23 @@ func TestListStopWatches(t *testing.T) { assert.Greater(t, apiWatches[0].Seconds, int64(0)) } } + +func TestUserLocationMapLink(t *testing.T) { + setting.Service.UserLocationMapURL = "https://example/foo/" + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user2") + req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ + "_csrf": GetCSRF(t, session, "/user/settings"), + "name": "user2", + "email": "user@example.com", + "language": "en-US", + "location": "A/b", + }) + session.MakeRequest(t, req, http.StatusSeeOther) + + req = NewRequest(t, "GET", "/user2/") + resp := session.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + htmlDoc.AssertElement(t, `a[href="https://example/foo/A%2Fb"]`, true) +} diff --git a/web_src/css/user.css b/web_src/css/user.css index 9fcdb3814a..ab94c826b2 100644 --- a/web_src/css/user.css +++ b/web_src/css/user.css @@ -22,18 +22,16 @@ .user.profile .ui.card .extra.content > ul > li { padding: 10px; + display: flex; list-style: none; + align-items: center; + gap: 0.25em; } .user.profile .ui.card .extra.content > ul > li:not(:last-child) { border-bottom: 1px solid var(--color-secondary); } -.user.profile .ui.card .extra.content > ul > li .svg { - margin-left: 1px; - margin-right: 5px; -} - .user.profile .ui.card .extra.content > ul > li.follow .ui.button { width: 100%; } |