-13
.editorconfig
-13
.editorconfig
+9
-4
appview/issues/issues.go
+9
-4
appview/issues/issues.go
···
312
312
// notify about the issue closure
313
313
rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Did), issue)
314
314
315
-
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId))
315
+
ownerSlashRepo := rp.repoResolver.GetBaseRepoPath(r, &f.Repo)
316
+
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
316
317
return
317
318
} else {
318
319
l.Error("user is not permitted to close issue")
···
362
363
// notify about the issue reopen
363
364
rp.notifier.NewIssueState(r.Context(), syntax.DID(user.Did), issue)
364
365
365
-
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId))
366
+
ownerSlashRepo := rp.repoResolver.GetBaseRepoPath(r, &f.Repo)
367
+
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
366
368
return
367
369
} else {
368
370
l.Error("user is not the owner of the repo")
···
466
468
}
467
469
rp.notifier.NewIssueComment(r.Context(), &comment, mentions)
468
470
469
-
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d#comment-%d", f.OwnerSlashRepo(), issue.IssueId, commentId))
471
+
ownerSlashRepo := rp.repoResolver.GetBaseRepoPath(r, &f.Repo)
472
+
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d#comment-%d", ownerSlashRepo, issue.IssueId, commentId))
470
473
}
471
474
472
475
func (rp *Issues) IssueComment(w http.ResponseWriter, r *http.Request) {
···
970
973
}
971
974
}
972
975
rp.notifier.NewIssue(r.Context(), issue, mentions)
973
-
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId))
976
+
977
+
ownerSlashRepo := rp.repoResolver.GetBaseRepoPath(r, &f.Repo)
978
+
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", ownerSlashRepo, issue.IssueId))
974
979
return
975
980
}
976
981
}
+2
-2
appview/middleware/middleware.go
+2
-2
appview/middleware/middleware.go
···
164
164
ok, err := mw.enforcer.E.Enforce(actor.Did, f.Knot, f.DidSlashRepo(), requiredPerm)
165
165
if err != nil || !ok {
166
166
// we need a logged in user
167
-
log.Printf("%s does not have perms of a %s in repo %s", actor.Did, requiredPerm, f.OwnerSlashRepo())
167
+
log.Printf("%s does not have perms of a %s in repo %s", actor.Did, requiredPerm, f.DidSlashRepo())
168
168
http.Error(w, "Forbiden", http.StatusUnauthorized)
169
169
return
170
170
}
···
327
327
return
328
328
}
329
329
330
-
fullName := f.OwnerHandle() + "/" + f.Name
330
+
fullName := mw.repoResolver.GetBaseRepoPath(r, &f.Repo)
331
331
332
332
if r.Header.Get("User-Agent") == "Go-http-client/1.1" {
333
333
if r.URL.Query().Get("go-get") == "1" {
+28
-8
appview/pages/funcmap.go
+28
-8
appview/pages/funcmap.go
···
22
22
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
23
23
"github.com/alecthomas/chroma/v2/lexers"
24
24
"github.com/alecthomas/chroma/v2/styles"
25
-
"github.com/bluesky-social/indigo/atproto/syntax"
26
25
"github.com/dustin/go-humanize"
27
26
"github.com/go-enry/go-enry/v2"
28
27
"tangled.org/core/appview/filetree"
28
+
"tangled.org/core/appview/models"
29
29
"tangled.org/core/appview/pages/markup"
30
30
"tangled.org/core/crypto"
31
31
)
···
70
70
}
71
71
72
72
return identity.Handle.String()
73
+
},
74
+
"ownerSlashRepo": func(repo *models.Repo) string {
75
+
ownerId, err := p.resolver.ResolveIdent(context.Background(), repo.Did)
76
+
if err != nil {
77
+
return repo.DidSlashRepo()
78
+
}
79
+
handle := ownerId.Handle
80
+
if handle != "" && !handle.IsInvalidHandle() {
81
+
return string(handle)+"/"+repo.Name
82
+
}
83
+
return repo.DidSlashRepo()
73
84
},
74
85
"truncateAt30": func(s string) string {
75
86
if len(s) <= 30 {
···
130
141
}
131
142
132
143
return b
133
-
},
134
-
"didOrHandle": func(did, handle string) string {
135
-
if handle != "" && handle != syntax.HandleInvalid.String() {
136
-
return handle
137
-
} else {
138
-
return did
139
-
}
140
144
},
141
145
"assoc": func(values ...string) ([][]string, error) {
142
146
if len(values)%2 != 0 {
···
369
373
}
370
374
}
371
375
376
+
func (p *Pages) resolveDid(did string) string {
377
+
identity, err := p.resolver.ResolveIdent(context.Background(), did)
378
+
379
+
if err != nil {
380
+
return did
381
+
}
382
+
383
+
if identity.Handle.IsInvalidHandle() {
384
+
return "handle.invalid"
385
+
}
386
+
387
+
return identity.Handle.String()
388
+
}
389
+
372
390
func (p *Pages) AvatarUrl(handle, size string) string {
373
391
handle = strings.TrimPrefix(handle, "@")
392
+
393
+
handle = p.resolveDid(handle)
374
394
375
395
secret := p.avatar.SharedSecret
376
396
h := hmac.New(sha256.New, []byte(secret))
-2
appview/pages/pages.go
-2
appview/pages/pages.go
···
482
482
483
483
type ProfileCard struct {
484
484
UserDid string
485
-
UserHandle string
486
485
FollowStatus models.FollowStatus
487
486
Punchcard *models.Punchcard
488
487
Profile *models.Profile
···
832
831
833
832
type Collaborator struct {
834
833
Did string
835
-
Handle string
836
834
Role string
837
835
}
838
836
+4
-4
appview/pages/repoinfo/repoinfo.go
+4
-4
appview/pages/repoinfo/repoinfo.go
···
9
9
"tangled.org/core/appview/state/userutil"
10
10
)
11
11
12
-
func (r RepoInfo) Owner() string {
12
+
func (r RepoInfo) owner() string {
13
13
if r.OwnerHandle != "" {
14
14
return r.OwnerHandle
15
15
} else {
···
18
18
}
19
19
20
20
func (r RepoInfo) FullName() string {
21
-
return path.Join(r.Owner(), r.Name)
21
+
return path.Join(r.owner(), r.Name)
22
22
}
23
23
24
-
func (r RepoInfo) OwnerWithoutAt() string {
24
+
func (r RepoInfo) ownerWithoutAt() string {
25
25
if r.OwnerHandle != "" {
26
26
return r.OwnerHandle
27
27
} else {
···
30
30
}
31
31
32
32
func (r RepoInfo) FullNameWithoutAt() string {
33
-
return path.Join(r.OwnerWithoutAt(), r.Name)
33
+
return path.Join(r.ownerWithoutAt(), r.Name)
34
34
}
35
35
36
36
func (r RepoInfo) GetTabs() [][]string {
+8
-7
appview/pages/templates/layouts/profilebase.html
+8
-7
appview/pages/templates/layouts/profilebase.html
···
1
-
{{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }}{{ end }}
1
+
{{ define "title" }}{{ resolve .Card.UserDid }}{{ end }}
2
2
3
3
{{ define "extrameta" }}
4
-
{{ $avatarUrl := fullAvatar .Card.UserHandle }}
5
-
<meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}" />
4
+
{{ $handle := resolve .Card.UserDid }}
5
+
{{ $avatarUrl := fullAvatar $handle }}
6
+
<meta property="og:title" content="{{ $handle }}" />
6
7
<meta property="og:type" content="profile" />
7
-
<meta property="og:url" content="https://tangled.org/{{ or .Card.UserHandle .Card.UserDid }}?tab={{ .Active }}" />
8
-
<meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" />
8
+
<meta property="og:url" content="https://tangled.org/{{ $handle }}?tab={{ .Active }}" />
9
+
<meta property="og:description" content="{{ or .Card.Profile.Description $handle }}" />
9
10
<meta property="og:image" content="{{ $avatarUrl }}" />
10
11
<meta property="og:image:width" content="512" />
11
12
<meta property="og:image:height" content="512" />
12
13
13
14
<meta name="twitter:card" content="summary" />
14
-
<meta name="twitter:title" content="{{ or .Card.UserHandle .Card.UserDid }}" />
15
-
<meta name="twitter:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" />
15
+
<meta name="twitter:title" content="{{ $handle }}" />
16
+
<meta name="twitter:description" content="{{ or .Card.Profile.Description $handle }}" />
16
17
<meta name="twitter:image" content="{{ $avatarUrl }}" />
17
18
{{ end }}
18
19
+1
-1
appview/pages/templates/repo/empty.html
+1
-1
appview/pages/templates/repo/empty.html
···
35
35
36
36
<p><span class="{{$bullet}}">1</span>First, generate a new <a href="https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key" class="underline">SSH key pair</a>.</p>
37
37
<p><span class="{{$bullet}}">2</span>Then add the public key to your account from the <a href="/settings" class="underline">settings</a> page.</p>
38
-
<p><span class="{{$bullet}}">3</span>Configure your remote to <code>git@{{ $knot | stripPort }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }}</code></p>
38
+
<p><span class="{{$bullet}}">3</span>Configure your remote to <code>git@{{ $knot | stripPort }}:{{ resolve .RepoInfo.OwnerDid }}/{{ .RepoInfo.Name }}</code></p>
39
39
<p><span class="{{$bullet}}">4</span>Push!</p>
40
40
</div>
41
41
</div>
+3
-2
appview/pages/templates/repo/fragments/cloneDropdown.html
+3
-2
appview/pages/templates/repo/fragments/cloneDropdown.html
···
43
43
44
44
<!-- SSH Clone -->
45
45
<div class="mb-3">
46
+
{{ $repoOwnerHandle := resolve .RepoInfo.OwnerDid }}
46
47
<label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">SSH</label>
47
48
<div class="flex items-center border border-gray-300 dark:border-gray-600 rounded">
48
49
<code
49
50
class="flex-1 px-3 py-2 text-sm bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-l select-all cursor-pointer whitespace-nowrap overflow-x-auto"
50
51
onclick="window.getSelection().selectAllChildren(this)"
51
-
data-url="git@{{ $knot | stripPort }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }}"
52
-
>git@{{ $knot | stripPort }}:{{ .RepoInfo.OwnerHandle }}/{{ .RepoInfo.Name }}</code>
52
+
data-url="git@{{ $knot | stripPort }}:{{ $repoOwnerHandle }}/{{ .RepoInfo.Name }}"
53
+
>git@{{ $knot | stripPort }}:{{ $repoOwnerHandle }}/{{ .RepoInfo.Name }}</code>
53
54
<button
54
55
onclick="copyToClipboard(this, this.previousElementSibling.getAttribute('data-url'))"
55
56
class="px-3 py-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 border-l border-gray-300 dark:border-gray-600"
+5
-4
appview/pages/templates/repo/settings/access.html
+5
-4
appview/pages/templates/repo/settings/access.html
···
29
29
{{ template "addCollaboratorButton" . }}
30
30
{{ end }}
31
31
{{ range .Collaborators }}
32
+
{{ $handle := resolve .Did }}
32
33
<div class="border border-gray-200 dark:border-gray-700 rounded p-4">
33
34
<div class="flex items-center gap-3">
34
35
<img
35
-
src="{{ fullAvatar .Handle }}"
36
-
alt="{{ .Handle }}"
36
+
src="{{ fullAvatar $handle }}"
37
+
alt="{{ $handle }}"
37
38
class="rounded-full h-10 w-10 border border-gray-300 dark:border-gray-600 flex-shrink-0"/>
38
39
39
40
<div class="flex-1 min-w-0">
40
-
<a href="/{{ .Handle }}" class="block truncate">
41
-
{{ didOrHandle .Did .Handle }}
41
+
<a href="/{{ $handle }}" class="block truncate">
42
+
{{ $handle }}
42
43
</a>
43
44
<p class="text-sm text-gray-500 dark:text-gray-400">{{ .Role }}</p>
44
45
</div>
+6
-5
appview/pages/templates/strings/dashboard.html
+6
-5
appview/pages/templates/strings/dashboard.html
···
1
-
{{ define "title" }}strings by {{ or .Card.UserHandle .Card.UserDid }}{{ end }}
1
+
{{ define "title" }}strings by {{ resolve .Card.UserDid }}{{ end }}
2
2
3
3
{{ define "extrameta" }}
4
-
<meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}" />
4
+
{{ $handle := resolve .Card.UserDid }}
5
+
<meta property="og:title" content="{{ $handle }}" />
5
6
<meta property="og:type" content="profile" />
6
-
<meta property="og:url" content="https://tangled.org/{{ or .Card.UserHandle .Card.UserDid }}" />
7
-
<meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" />
7
+
<meta property="og:url" content="https://tangled.org/{{ $handle }}" />
8
+
<meta property="og:description" content="{{ or .Card.Profile.Description $handle }}" />
8
9
{{ end }}
9
10
10
11
···
35
36
{{ $s := index . 1 }}
36
37
<div class="py-4 px-6 drop-shadow-sm rounded bg-white dark:bg-gray-800">
37
38
<div class="font-medium dark:text-white flex gap-2 items-center">
38
-
<a href="/strings/{{ or $root.Card.UserHandle $root.Card.UserDid }}/{{ $s.Rkey }}">{{ $s.Filename }}</a>
39
+
<a href="/strings/{{ resolve $root.Card.UserDid }}/{{ $s.Rkey }}">{{ $s.Filename }}</a>
39
40
</div>
40
41
{{ with $s.Description }}
41
42
<div class="text-gray-600 dark:text-gray-300 text-sm">
+3
-3
appview/pages/templates/strings/string.html
+3
-3
appview/pages/templates/strings/string.html
···
1
-
{{ define "title" }}{{ .String.Filename }} · by {{ didOrHandle .Owner.DID.String .Owner.Handle.String }}{{ end }}
1
+
{{ define "title" }}{{ .String.Filename }} · by {{ resolve .Owner.DID.String }}{{ end }}
2
2
3
3
{{ define "extrameta" }}
4
-
{{ $ownerId := didOrHandle .Owner.DID.String .Owner.Handle.String }}
4
+
{{ $ownerId := resolve .Owner.DID.String }}
5
5
<meta property="og:title" content="{{ .String.Filename }} · by {{ $ownerId }}" />
6
6
<meta property="og:type" content="object" />
7
7
<meta property="og:url" content="https://tangled.org/strings/{{ $ownerId }}/{{ .String.Rkey }}" />
···
9
9
{{ end }}
10
10
11
11
{{ define "content" }}
12
-
{{ $ownerId := didOrHandle .Owner.DID.String .Owner.Handle.String }}
12
+
{{ $ownerId := resolve .Owner.DID.String }}
13
13
<section id="string-header" class="mb-4 py-2 px-6 dark:text-white">
14
14
<div class="text-lg flex items-center justify-between">
15
15
<div>
+1
-1
appview/pages/templates/user/followers.html
+1
-1
appview/pages/templates/user/followers.html
+1
-1
appview/pages/templates/user/following.html
+1
-1
appview/pages/templates/user/following.html
+1
-1
appview/pages/templates/user/fragments/profileCard.html
+1
-1
appview/pages/templates/user/fragments/profileCard.html
···
1
1
{{ define "user/fragments/profileCard" }}
2
-
{{ $userIdent := didOrHandle .UserDid .UserHandle }}
2
+
{{ $userIdent := resolve .UserDid }}
3
3
<div class="grid grid-cols-3 md:grid-cols-1 gap-1 items-center">
4
4
<div id="avatar" class="col-span-1 flex justify-center items-center">
5
5
<div class="w-3/4 aspect-square relative">
+2
-2
appview/pages/templates/user/overview.html
+2
-2
appview/pages/templates/user/overview.html
···
1
-
{{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }}{{ end }}
1
+
{{ define "title" }}{{ resolve .Card.UserDid }}{{ end }}
2
2
3
3
{{ define "profileContent" }}
4
4
<div id="all-repos" class="md:col-span-4 order-2 md:order-2">
···
224
224
{{ define "ownRepos" }}
225
225
<div>
226
226
<div class="text-sm font-bold px-2 pb-4 dark:text-white flex items-center gap-2">
227
-
<a href="/@{{ or $.Card.UserHandle $.Card.UserDid }}?tab=repos"
227
+
<a href="/{{ resolve $.Card.UserDid }}?tab=repos"
228
228
class="flex text-black dark:text-white items-center gap-2 no-underline hover:no-underline group">
229
229
<span>PINNED REPOS</span>
230
230
</a>
+1
-1
appview/pages/templates/user/repos.html
+1
-1
appview/pages/templates/user/repos.html
+1
-1
appview/pages/templates/user/starred.html
+1
-1
appview/pages/templates/user/starred.html
+2
-2
appview/pages/templates/user/strings.html
+2
-2
appview/pages/templates/user/strings.html
···
1
-
{{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }} · strings {{ end }}
1
+
{{ define "title" }}{{ resolve .Card.UserDid }} · strings {{ end }}
2
2
3
3
{{ define "profileContent" }}
4
4
<div id="all-strings" class="md:col-span-8 order-2 md:order-2">
···
23
23
{{ $s := index . 1 }}
24
24
<div class="py-4 px-6 rounded bg-white dark:bg-gray-800">
25
25
<div class="font-medium dark:text-white flex gap-2 items-center">
26
-
<a href="/strings/{{ or $root.Card.UserHandle $root.Card.UserDid }}/{{ $s.Rkey }}">{{ $s.Filename }}</a>
26
+
<a href="/strings/{{ resolve $root.Card.UserDid }}/{{ $s.Rkey }}">{{ $s.Filename }}</a>
27
27
</div>
28
28
{{ with $s.Description }}
29
29
<div class="text-gray-600 dark:text-gray-300 text-sm">
+16
-8
appview/pulls/pulls.go
+16
-8
appview/pulls/pulls.go
···
800
800
}
801
801
s.notifier.NewPullComment(r.Context(), comment, mentions)
802
802
803
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d#comment-%d", f.OwnerSlashRepo(), pull.PullId, commentId))
803
+
ownerSlashRepo := s.repoResolver.GetBaseRepoPath(r, &f.Repo)
804
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d#comment-%d", ownerSlashRepo, pull.PullId, commentId))
804
805
return
805
806
}
806
807
}
···
1271
1272
1272
1273
s.notifier.NewPull(r.Context(), pull)
1273
1274
1274
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pullId))
1275
+
ownerSlashRepo := s.repoResolver.GetBaseRepoPath(r, &f.Repo)
1276
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pullId))
1275
1277
}
1276
1278
1277
1279
func (s *Pulls) createStackedPullRequest(
···
1372
1374
return
1373
1375
}
1374
1376
1375
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls", f.OwnerSlashRepo()))
1377
+
ownerSlashRepo := s.repoResolver.GetBaseRepoPath(r, &f.Repo)
1378
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls", ownerSlashRepo))
1376
1379
}
1377
1380
1378
1381
func (s *Pulls) ValidatePatch(w http.ResponseWriter, r *http.Request) {
···
1920
1923
return
1921
1924
}
1922
1925
1923
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
1926
+
ownerSlashRepo := s.repoResolver.GetBaseRepoPath(r, &f.Repo)
1927
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pull.PullId))
1924
1928
}
1925
1929
1926
1930
func (s *Pulls) resubmitStackedPullHelper(
···
2113
2117
return
2114
2118
}
2115
2119
2116
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
2120
+
ownerSlashRepo := s.repoResolver.GetBaseRepoPath(r, &f.Repo)
2121
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pull.PullId))
2117
2122
}
2118
2123
2119
2124
func (s *Pulls) MergePull(w http.ResponseWriter, r *http.Request) {
···
2231
2236
s.notifier.NewPullState(r.Context(), syntax.DID(user.Did), p)
2232
2237
}
2233
2238
2234
-
s.pages.HxLocation(w, fmt.Sprintf("/@%s/%s/pulls/%d", f.OwnerHandle(), f.Name, pull.PullId))
2239
+
ownerSlashRepo := s.repoResolver.GetBaseRepoPath(r, &f.Repo)
2240
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pull.PullId))
2235
2241
}
2236
2242
2237
2243
func (s *Pulls) ClosePull(w http.ResponseWriter, r *http.Request) {
···
2303
2309
s.notifier.NewPullState(r.Context(), syntax.DID(user.Did), p)
2304
2310
}
2305
2311
2306
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
2312
+
ownerSlashRepo := s.repoResolver.GetBaseRepoPath(r, &f.Repo)
2313
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pull.PullId))
2307
2314
}
2308
2315
2309
2316
func (s *Pulls) ReopenPull(w http.ResponseWriter, r *http.Request) {
···
2376
2383
s.notifier.NewPullState(r.Context(), syntax.DID(user.Did), p)
2377
2384
}
2378
2385
2379
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
2386
+
ownerSlashRepo := s.repoResolver.GetBaseRepoPath(r, &f.Repo)
2387
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", ownerSlashRepo, pull.PullId))
2380
2388
}
2381
2389
2382
2390
func newStack(f *reporesolver.ResolvedRepo, user *oauth.User, targetBranch, patch string, pullSource *models.PullSource, stackId string) (models.Stack, error) {
+3
-1
appview/repo/blob.go
+3
-1
appview/repo/blob.go
···
62
62
return
63
63
}
64
64
65
+
ownerSlashRepo := rp.repoResolver.GetBaseRepoPath(r, &f.Repo)
66
+
65
67
// Use XRPC response directly instead of converting to internal types
66
68
var breadcrumbs [][]string
67
-
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", f.OwnerSlashRepo(), url.PathEscape(ref))})
69
+
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", ownerSlashRepo, url.PathEscape(ref))})
68
70
if filePath != "" {
69
71
for idx, elem := range strings.Split(filePath, "/") {
70
72
breadcrumbs = append(breadcrumbs, []string{elem, fmt.Sprintf("%s/%s", breadcrumbs[idx][1], url.PathEscape(elem))})
+3
-2
appview/repo/tree.go
+3
-2
appview/repo/tree.go
···
79
79
result.ReadmeFileName = xrpcResp.Readme.Filename
80
80
result.Readme = xrpcResp.Readme.Contents
81
81
}
82
+
ownerSlashRepo := rp.repoResolver.GetBaseRepoPath(r, &f.Repo)
82
83
// redirects tree paths trying to access a blob; in this case the result.Files is unpopulated,
83
84
// so we can safely redirect to the "parent" (which is the same file).
84
85
if len(result.Files) == 0 && result.Parent == treePath {
85
-
redirectTo := fmt.Sprintf("/%s/blob/%s/%s", f.OwnerSlashRepo(), url.PathEscape(ref), result.Parent)
86
+
redirectTo := fmt.Sprintf("/%s/blob/%s/%s", ownerSlashRepo, url.PathEscape(ref), result.Parent)
86
87
http.Redirect(w, r, redirectTo, http.StatusFound)
87
88
return
88
89
}
89
90
user := rp.oauth.GetUser(r)
90
91
var breadcrumbs [][]string
91
-
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", f.OwnerSlashRepo(), url.PathEscape(ref))})
92
+
breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", ownerSlashRepo, url.PathEscape(ref))})
92
93
if treePath != "" {
93
94
for idx, elem := range strings.Split(treePath, "/") {
94
95
breadcrumbs = append(breadcrumbs, []string{elem, fmt.Sprintf("%s/%s", breadcrumbs[idx][1], url.PathEscape(elem))})
+12
-14
appview/reporesolver/resolver.go
+12
-14
appview/reporesolver/resolver.go
···
44
44
return &RepoResolver{config: config, enforcer: enforcer, idResolver: resolver, execer: execer}
45
45
}
46
46
47
+
// NOTE: this... should not even be here. the entire package will be removed in future refactor
48
+
func (rr *RepoResolver) GetBaseRepoPath(r *http.Request, repo *models.Repo) string {
49
+
var (
50
+
user = chi.URLParam(r, "user")
51
+
name = chi.URLParam(r, "repo")
52
+
)
53
+
if user == "" || name == "" {
54
+
return repo.DidSlashRepo()
55
+
}
56
+
return path.Join(user, name)
57
+
}
58
+
47
59
func (rr *RepoResolver) Resolve(r *http.Request) (*ResolvedRepo, error) {
48
60
repo, ok := r.Context().Value("repo").(*models.Repo)
49
61
if !ok {
···
113
125
114
126
c := pages.Collaborator{
115
127
Did: did,
116
-
Handle: "",
117
128
Role: role,
118
129
}
119
130
collaborators = append(collaborators, c)
120
-
}
121
-
122
-
// populate all collborators with handles
123
-
identsToResolve := make([]string, len(collaborators))
124
-
for i, collab := range collaborators {
125
-
identsToResolve[i] = collab.Did
126
-
}
127
-
128
-
resolvedIdents := f.rr.idResolver.ResolveIdents(ctx, identsToResolve)
129
-
for i, resolved := range resolvedIdents {
130
-
if resolved != nil {
131
-
collaborators[i].Handle = resolved.Handle.String()
132
-
}
133
131
}
134
132
135
133
return collaborators, nil
+5
-6
appview/state/profile.go
+5
-6
appview/state/profile.go
···
96
96
97
97
return &pages.ProfileCard{
98
98
UserDid: did,
99
-
UserHandle: ident.Handle.String(),
100
99
Profile: profile,
101
100
FollowStatus: followStatus,
102
101
Stats: pages.ProfileStats{
···
119
118
s.pages.Error500(w)
120
119
return
121
120
}
122
-
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
121
+
l = l.With("profileDid", profile.UserDid)
123
122
124
123
repos, err := db.GetRepos(
125
124
s.db,
···
180
179
s.pages.Error500(w)
181
180
return
182
181
}
183
-
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
182
+
l = l.With("profileDid", profile.UserDid)
184
183
185
184
repos, err := db.GetRepos(
186
185
s.db,
···
209
208
s.pages.Error500(w)
210
209
return
211
210
}
212
-
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
211
+
l = l.With("profileDid", profile.UserDid)
213
212
214
213
stars, err := db.GetStars(s.db, 0, db.FilterEq("starred_by_did", profile.UserDid))
215
214
if err != nil {
···
240
239
s.pages.Error500(w)
241
240
return
242
241
}
243
-
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
242
+
l = l.With("profileDid", profile.UserDid)
244
243
245
244
strings, err := db.GetStrings(s.db, 0, db.FilterEq("did", profile.UserDid))
246
245
if err != nil {
···
272
271
if err != nil {
273
272
return nil, err
274
273
}
275
-
l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle)
274
+
l = l.With("profileDid", profile.UserDid)
276
275
277
276
loggedInUser := s.oauth.GetUser(r)
278
277
params := FollowsPageParams{