Signed-off-by: brookjeynes me@brookjeynes.dev
+30
-5
internal/server/handlers/router.go
+30
-5
internal/server/handlers/router.go
···
10
10
"yoten.app/internal/server/log"
11
11
"yoten.app/internal/server/middleware"
12
12
"yoten.app/internal/server/views"
13
+
"yoten.app/internal/utils"
13
14
)
14
15
15
16
type Handler struct {
···
29
30
log.SubLogger(h.Logger, "middleware"),
30
31
)
31
32
33
+
router.Get("/pwa-manifest.json", h.PWAManifest)
34
+
35
+
userRouter := h.UserRouter(&middleware)
36
+
standardRouter := h.StandardRouter(&middleware)
37
+
32
38
router.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) {
33
39
pat := chi.URLParam(r, "*")
34
-
if strings.HasPrefix(pat, "did:") || strings.HasPrefix(pat, "@") {
35
-
h.UserRouter(&middleware).ServeHTTP(w, r)
36
-
} else {
37
-
h.StandardRouter(&middleware).ServeHTTP(w, r)
40
+
pathParts := strings.SplitN(pat, "/", 2)
41
+
42
+
if len(pathParts) > 0 {
43
+
firstPart := pathParts[0]
44
+
45
+
// if using a DID or handle, just continue as per usual
46
+
if utils.IsDid(firstPart) || utils.IsHandle(firstPart) {
47
+
userRouter.ServeHTTP(w, r)
48
+
return
49
+
}
50
+
51
+
// if using a handle with @, rewrite to work without @
52
+
if normalized := strings.TrimPrefix(firstPart, "@"); utils.IsHandle(normalized) {
53
+
redirectPath := strings.Join(append([]string{normalized}, pathParts[1:]...), "/")
54
+
55
+
redirectURL := *r.URL
56
+
redirectURL.Path = "/" + redirectPath
57
+
58
+
http.Redirect(w, r, redirectURL.String(), http.StatusFound)
59
+
return
60
+
}
61
+
38
62
}
63
+
64
+
standardRouter.ServeHTTP(w, r)
39
65
})
40
66
41
67
return router
···
48
74
r.Handle("/static/*", h.HandleStatic())
49
75
r.Get("/favicon.svg", h.HandleFavicon)
50
76
r.Get("/favicon.ico", h.HandleFavicon)
51
-
r.Get("/pwa-manifest.json", h.PWAManifest)
52
77
53
78
r.Get("/", h.HandleIndexPage)
54
79
r.Get("/feed", h.HandleStudySessionFeed)
+1
-1
internal/server/views/edit-profile.templ
+1
-1
internal/server/views/edit-profile.templ
···
145
145
<i class="w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" data-lucide="loader-circle"></i>
146
146
</button>
147
147
<button id="cancel-button" type="button" class="w-full">
148
-
<a href={ templ.SafeURL(fmt.Sprintf("/@%s", params.User.Did)) } class="btn btn-secondary">
148
+
<a href={ templ.SafeURL(fmt.Sprintf("/%s", params.User.Did)) } class="btn btn-secondary">
149
149
Cancel
150
150
</a>
151
151
</button>
+8
-8
internal/server/views/new-study-session.templ
+8
-8
internal/server/views/new-study-session.templ
···
18
18
19
19
activityName := "Select an activity"
20
20
if params.QueryParams.ActivityId != "" {
21
-
activityId, err := strconv.ParseInt(params.QueryParams.ActivityId, 10, 64)
22
-
if err == nil {
23
-
for _, a := range params.Activities {
24
-
if int64(a.ID) == activityId {
25
-
activityName = a.Name
26
-
}
27
-
}
28
-
}
21
+
activityId, err := strconv.ParseInt(params.QueryParams.ActivityId, 10, 64)
22
+
if err == nil {
23
+
for _, a := range params.Activities {
24
+
if int64(a.ID) == activityId {
25
+
activityName = a.Name
26
+
}
27
+
}
28
+
}
29
29
}
30
30
}}
31
31
@layouts.Base(layouts.BaseParams{Title: "new study session"}) {
+1
-1
internal/server/views/partials/comment.templ
+1
-1
internal/server/views/partials/comment.templ
···
16
16
}
17
17
<div>
18
18
<div class="flex items-center gap-2">
19
-
<a href={ templ.URL(fmt.Sprintf("/@%s", params.Comment.Did)) } class="font-semibold">
19
+
<a href={ templ.URL(fmt.Sprintf("/%s", params.Comment.Did)) } class="font-semibold">
20
20
{ params.Comment.ProfileDisplayName }
21
21
</a>
22
22
<p class="pill pill-secondary px-2 py-0.5 h-fit items-center justify-center gap-1 w-fit flex">
+1
-1
internal/server/views/partials/header.templ
+1
-1
internal/server/views/partials/header.templ
···
39
39
class="absolute flex flex-col right-0 mt-2 p-1 gap-1 rounded w-48 bg-bg-light border border-bg-dark"
40
40
>
41
41
<a
42
-
href={ templ.URL(fmt.Sprintf("/@%s", params.User.BskyProfile.Handle)) }
42
+
href={ templ.URL(fmt.Sprintf("/%s", params.User.BskyProfile.Handle)) }
43
43
class="flex items-center px-4 py-2 text-sm hover:bg-bg gap-2"
44
44
>
45
45
<i class="w-4 h-4" data-lucide="user"></i>
+1
-1
internal/server/views/partials/profile.templ
+1
-1
internal/server/views/partials/profile.templ
···
18
18
}
19
19
<div>
20
20
<div class="flex items-center gap-2">
21
-
<a href={ templ.SafeURL(fmt.Sprintf("/@%s", params.Profile.Did)) } class="font-semibold">
21
+
<a href={ templ.SafeURL(fmt.Sprintf("/%s", params.Profile.Did)) } class="font-semibold">
22
22
{ params.Profile.DisplayName }
23
23
</a>
24
24
<p class="pill pill-secondary h-fit items-center justify-center gap-1 w-fit hidden sm:flex">
+1
-1
internal/server/views/partials/reply.templ
+1
-1
internal/server/views/partials/reply.templ
···
16
16
}
17
17
<div>
18
18
<div class="flex items-center gap-2">
19
-
<a href={ templ.URL(fmt.Sprintf("/@%s", props.Reply.Did)) } class="font-semibold">
19
+
<a href={ templ.URL(fmt.Sprintf("/%s", props.Reply.Did)) } class="font-semibold">
20
20
{ props.Reply.ProfileDisplayName }
21
21
</a>
22
22
<p class="pill pill-secondary px-2 py-0.5 h-fit items-center justify-center gap-1 w-fit flex">
+1
-1
internal/server/views/partials/study-session.templ
+1
-1
internal/server/views/partials/study-session.templ
···
83
83
}
84
84
<div>
85
85
<div class="flex items-center gap-2">
86
-
<a href={ templ.URL(fmt.Sprintf("/@%s", params.StudySession.Did)) } class="font-semibold">
86
+
<a href={ templ.URL(fmt.Sprintf("/%s", params.StudySession.Did)) } class="font-semibold">
87
87
{ params.StudySession.ProfileDisplayName }
88
88
</a>
89
89
<p class="pill pill-secondary px-2 py-0.5 h-fit items-center justify-center gap-1 w-fit flex">
+20
internal/utils/userutil.go
+20
internal/utils/userutil.go
···
1
+
package utils
2
+
3
+
import (
4
+
"regexp"
5
+
)
6
+
7
+
var (
8
+
// ref: https://atproto.com/specs/handle
9
+
handleRegex = regexp.MustCompile(`^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$`)
10
+
// ref: https://atproto.com/specs/did
11
+
didRegex = regexp.MustCompile(`^did:[a-z]+:[a-zA-Z0-9._:%-]*[a-zA-Z0-9._-]$`)
12
+
)
13
+
14
+
func IsHandle(s string) bool {
15
+
return handleRegex.MatchString(s)
16
+
}
17
+
18
+
func IsDid(s string) bool {
19
+
return didRegex.MatchString(s)
20
+
}
History
1 round
0 comments
brookjeynes.dev
submitted
#0
1 commit
expand
collapse
feat: remove need for '@' for user urls
Signed-off-by: brookjeynes <me@brookjeynes.dev>
expand 0 comments
pull request successfully merged