Skip to content

Commit d58c542

Browse files
n0tooseGustedcaesarwxiaoguang
authored
Add 'Show on a map' button to Location in profile, fix layout (#26214)
Not too important, but I think that it'd be a pretty neat touch. Also fixes some layout bugs introduced by a previous PR. --------- Co-authored-by: Gusted <postmaster@gusted.xyz> Co-authored-by: Caesar Schinas <caesar@caesarschinas.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1 parent 72363be commit d58c542

File tree

9 files changed

+54
-11
lines changed

9 files changed

+54
-11
lines changed

custom/conf/app.example.ini

+9
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,15 @@ LEVEL = Info
827827
;; Dependencies can be added from any repository where the user is granted access or only from the current repository depending on this setting.
828828
;ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true
829829
;;
830+
;; Default map service. No external API support has been included. A service has to allow
831+
;; searching using URL parameters, the location will be appended to the URL as escaped query parameter.
832+
;; Disabled by default, some example values are:
833+
;; - OpenStreetMap: https://www.openstreetmap.org/search?query=
834+
;; - Google Maps: https://www.google.com/maps/place/
835+
;; - MapQuest: https://www.mapquest.com/search/
836+
;; - Bing Maps: https://www.bing.com/maps?where1=
837+
; USER_LOCATION_MAP_URL =
838+
;;
830839
;; Enable heatmap on users profiles.
831840
;ENABLE_USER_HEATMAP = true
832841
;;

docs/content/administration/config-cheat-sheet.en-us.md

+1
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ And the following unique queues:
648648
- `DEFAULT_USER_IS_RESTRICTED`: **false**: Give new users restricted permissions by default
649649
- `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default.
650650
- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access.
651+
- `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.
651652
- `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles.
652653
- `ENABLE_TIMETRACKING`: **true**: Enable Timetracking feature.
653654
- `DEFAULT_ENABLE_TIMETRACKING`: **true**: Allow repositories to use timetracking by default.

modules/setting/service.go

+2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ var Service = struct {
7373
AllowCrossRepositoryDependencies bool
7474
DefaultAllowOnlyContributorsToTrackTime bool
7575
NoReplyAddress string
76+
UserLocationMapURL string
7677
EnableUserHeatmap bool
7778
AutoWatchNewRepos bool
7879
AutoWatchOnChanges bool
@@ -185,6 +186,7 @@ func loadServiceFrom(rootCfg ConfigProvider) {
185186
Service.AllowCrossRepositoryDependencies = sec.Key("ALLOW_CROSS_REPOSITORY_DEPENDENCIES").MustBool(true)
186187
Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true)
187188
Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply." + Domain)
189+
Service.UserLocationMapURL = sec.Key("USER_LOCATION_MAP_URL").String()
188190
Service.EnableUserHeatmap = sec.Key("ENABLE_USER_HEATMAP").MustBool(true)
189191
Service.AutoWatchNewRepos = sec.Key("AUTO_WATCH_NEW_REPOS").MustBool(true)
190192
Service.AutoWatchOnChanges = sec.Key("AUTO_WATCH_ON_CHANGES").MustBool(false)

options/locale/locale_en-US.ini

+2
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,7 @@ user_bio = Biography
601601
disabled_public_activity = This user has disabled the public visibility of the activity.
602602
email_visibility.limited = Your email address is visible to all authenticated users
603603
email_visibility.private = Your email address is only visible to you and administrators
604+
show_on_map = Show this place on a map
604605

605606
form.name_reserved = The username "%s" is reserved.
606607
form.name_pattern_not_allowed = The pattern "%s" is not allowed in a username.
@@ -627,6 +628,7 @@ webauthn = Security Keys
627628

628629
public_profile = Public Profile
629630
biography_placeholder = Tell us a little bit about yourself
631+
location_placeholder = Share your approximate location with others
630632
profile_desc = Your email address will be used for notifications and other operations.
631633
password_username_disabled = Non-local users are not allowed to change their username. Please contact your site administrator for more details.
632634
full_name = Full Name

routers/web/user/profile.go

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func userProfile(ctx *context.Context) {
5252

5353
ctx.Data["Title"] = ctx.ContextUser.DisplayName()
5454
ctx.Data["PageIsUserProfile"] = true
55+
ctx.Data["UserLocationMapURL"] = setting.Service.UserLocationMapURL
5556

5657
// prepare heatmap data
5758
if setting.Service.EnableUserHeatmap {

templates/shared/user/profile_big_avatar.tmpl

+14-5
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,28 @@
2424
<div class="extra content gt-word-break">
2525
<ul>
2626
{{if .ContextUser.Location}}
27-
<li>{{svg "octicon-location"}} {{.ContextUser.Location}}</li>
27+
<li>
28+
{{svg "octicon-location"}}
29+
<span class="gt-f1">{{.ContextUser.Location}}</span>
30+
{{if .UserLocationMapURL}}
31+
{{/* We presume that the UserLocationMapURL is safe, as it is provided by the site administrator. */}}
32+
<a href="{{.UserLocationMapURL | Safe}}{{.ContextUser.Location | QueryEscape}}" rel="nofollow noreferrer" data-tooltip-content="{{.locale.Tr "user.show_on_map"}}">
33+
{{svg "octicon-link-external"}}
34+
</a>
35+
{{end}}
36+
</li>
2837
{{end}}
2938
{{if (eq .SignedUserID .ContextUser.ID)}}
3039
<li>
3140
{{svg "octicon-mail"}}
32-
<a href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
41+
<a class="gt-f1" href="mailto:{{.ContextUser.Email}}" rel="nofollow">{{.ContextUser.Email}}</a>
3342
<a href="{{AppSubUrl}}/user/settings#keep-email-private">
3443
{{if .ShowUserEmail}}
35-
<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}">
44+
<i data-tooltip-content="{{.locale.Tr "user.email_visibility.limited"}}">
3645
{{svg "octicon-unlock"}}
3746
</i>
3847
{{else}}
39-
<i class="ui right" data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}">
48+
<i data-tooltip-content="{{.locale.Tr "user.email_visibility.private"}}">
4049
{{svg "octicon-lock"}}
4150
</i>
4251
{{end}}
@@ -69,7 +78,7 @@
6978
</li>
7079
{{end}}
7180
{{end}}
72-
<li>{{svg "octicon-calendar"}} {{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</li>
81+
<li>{{svg "octicon-calendar"}} <span>{{.locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix) | Safe}}</span></li>
7382
{{if and .Orgs .HasOrgsVisible}}
7483
<li>
7584
<ul class="user-orgs">

templates/user/settings/profile.tmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
</div>
3636
<div class="field">
3737
<label for="location">{{.locale.Tr "settings.location"}}</label>
38-
<input id="location" name="location" value="{{.SignedUser.Location}}" maxlength="50">
38+
<input id="location" name="location" placeholder="{{.locale.Tr "settings.location_placeholder"}}" value="{{.SignedUser.Location}}" maxlength="50">
3939
</div>
4040

4141
<div class="divider"></div>

tests/integration/user_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
repo_model "code.gitea.io/gitea/models/repo"
1313
"code.gitea.io/gitea/models/unittest"
1414
user_model "code.gitea.io/gitea/models/user"
15+
"code.gitea.io/gitea/modules/setting"
1516
api "code.gitea.io/gitea/modules/structs"
1617
"code.gitea.io/gitea/modules/test"
1718
"code.gitea.io/gitea/modules/translation"
@@ -276,3 +277,23 @@ func TestListStopWatches(t *testing.T) {
276277
assert.Greater(t, apiWatches[0].Seconds, int64(0))
277278
}
278279
}
280+
281+
func TestUserLocationMapLink(t *testing.T) {
282+
setting.Service.UserLocationMapURL = "https://example/foo/"
283+
defer tests.PrepareTestEnv(t)()
284+
285+
session := loginUser(t, "user2")
286+
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
287+
"_csrf": GetCSRF(t, session, "/user/settings"),
288+
"name": "user2",
289+
"email": "user@example.com",
290+
"language": "en-US",
291+
"location": "A/b",
292+
})
293+
session.MakeRequest(t, req, http.StatusSeeOther)
294+
295+
req = NewRequest(t, "GET", "/user2/")
296+
resp := session.MakeRequest(t, req, http.StatusOK)
297+
htmlDoc := NewHTMLParser(t, resp.Body)
298+
htmlDoc.AssertElement(t, `a[href="https://example/foo/A%2Fb"]`, true)
299+
}

web_src/css/user.css

+3-5
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,16 @@
2222

2323
.user.profile .ui.card .extra.content > ul > li {
2424
padding: 10px;
25+
display: flex;
2526
list-style: none;
27+
align-items: center;
28+
gap: 0.25em;
2629
}
2730

2831
.user.profile .ui.card .extra.content > ul > li:not(:last-child) {
2932
border-bottom: 1px solid var(--color-secondary);
3033
}
3134

32-
.user.profile .ui.card .extra.content > ul > li .svg {
33-
margin-left: 1px;
34-
margin-right: 5px;
35-
}
36-
3735
.user.profile .ui.card .extra.content > ul > li.follow .ui.button {
3836
width: 100%;
3937
}

0 commit comments

Comments
 (0)