avatar and new header design

This commit is contained in:
Niko Abeler 2022-09-10 15:22:18 +02:00
parent ae29a0221c
commit 534dc3ba9b
7 changed files with 112 additions and 25 deletions

View File

@ -237,6 +237,26 @@ func postMediaHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Requ
}
}
func userMediaHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
filepath := ps.ByName("filepath")
user, err := getUserFromRepo(repo, ps)
if err != nil {
println("Error getting user: ", err.Error())
notFoundHandler(repo)(w, r)
return
}
filepath = path.Join(user.MediaDir(), filepath)
if _, err := os.Stat(filepath); err != nil {
println("Error getting file: ", err.Error())
notFoundHandler(repo)(w, r)
return
}
http.ServeFile(w, r, filepath)
}
}
func notFoundHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path

View File

@ -14,10 +14,11 @@ func Router(repo *owl.Repository) http.Handler {
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
router.GET("/", repoIndexHandler(repo))
router.GET("/user/:user/", userIndexHandler(repo))
router.POST("/user/:user/webmention/", userWebmentionHandler(repo))
router.GET("/user/:user/media/*filepath", userMediaHandler(repo))
router.GET("/user/:user/index.xml", userRSSHandler(repo))
router.GET("/user/:user/posts/:post/", postHandler(repo))
router.GET("/user/:user/posts/:post/media/*filepath", postMediaHandler(repo))
router.POST("/user/:user/webmention/", userWebmentionHandler(repo))
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
return router
}
@ -26,10 +27,11 @@ func SingleUserRouter(repo *owl.Repository) http.Handler {
router := httprouter.New()
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
router.GET("/", userIndexHandler(repo))
router.POST("/webmention/", userWebmentionHandler(repo))
router.GET("/media/*filepath", userMediaHandler(repo))
router.GET("/index.xml", userRSSHandler(repo))
router.GET("/posts/:post/", postHandler(repo))
router.GET("/posts/:post/media/*filepath", postMediaHandler(repo))
router.POST("/webmention/", userWebmentionHandler(repo))
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
return router
}

View File

@ -18,6 +18,26 @@
border-color: #ccc;
}
.avatar {
float: left;
margin-right: 1rem;
}
.header {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: flex-start;
}
.header-title {
order: 0;
}
.header-profile {
order: 1;
}
hgroup h2 a { color: inherit; }
</style>
@ -25,34 +45,34 @@
<body>
<header>
<nav class="container">
<ul>
<li>
<hgroup>
<h2><a href="{{ .User.UrlPath }}">{{ .UserConfig.Title }}</a></h2>
<h3>{{ .UserConfig.SubTitle }}</h3>
</hgroup>
</li>
</ul>
<div class="container header h-card">
<hgroup class="header-title">
<h2><a class="p-name u-url" href="{{ .User.UrlPath }}">{{ .UserConfig.Title }}</a></h2>
<h3>{{ .UserConfig.SubTitle }}</h3>
</hgroup>
</nav>
<div class="header-profile">
{{ if .User.AvatarUrl }}
<img class="u-logo avatar" src="{{ .User.AvatarUrl }}" alt="{{ .UserConfig.Title }}" width="100" height="100" />
{{ end }}
<div style="float: right; list-style: none;">
{{ if .UserConfig.TwitterHandle}}
<li><a href="https://twitter.com/{{.UserConfig.TwitterHandle}}" rel="me">@{{.UserConfig.TwitterHandle}} on Twitter</a>
</li>
{{ end }}
{{ if .UserConfig.GitHubHandle}}
<li><a href="https://github.com/{{.UserConfig.GitHubHandle}}" rel="me">@{{.UserConfig.GitHubHandle}} on GitHub</a>
</li>
{{ end }}
</div>
</div>
</div>
</header>
<main class="container">
{{ .Content }}
</main>
<footer class="container">
<nav>
<ul>
{{ if .UserConfig.TwitterHandle}}
<li><a href="https://twitter.com/{{.UserConfig.TwitterHandle}}" rel="me">@{{.UserConfig.TwitterHandle}} on Twitter</a>
</li>
{{ end }}
{{ if .UserConfig.GitHubHandle}}
<li><a href="https://github.com/{{.UserConfig.GitHubHandle}}" rel="me">@{{.UserConfig.GitHubHandle}} on GitHub</a>
</li>
{{ end }}
</ul>
</nav>
</footer>
</body>

View File

@ -251,3 +251,13 @@ func TestRenderIncludesFullUrl(t *testing.T) {
t.Error("Expected: " + post.FullUrl())
}
}
func TestAddAvatarIfExist(t *testing.T) {
user := getTestUser()
os.WriteFile(path.Join(user.MediaDir(), "avatar.png"), []byte("test"), 0644)
result, _ := owl.RenderIndexPage(user)
if !strings.Contains(result, "avatar.png") {
t.Error("Avatar not rendered. Got: " + result)
}
}

View File

@ -136,9 +136,10 @@ func (repo *Repository) CreateUser(name string) (User, error) {
// creates repo/name folder if it doesn't exist
user_dir := new_user.Dir()
os.Mkdir(user_dir, 0755)
// create folders
os.Mkdir(path.Join(user_dir, "meta"), 0755)
// create public folder
os.Mkdir(path.Join(user_dir, "public"), 0755)
os.Mkdir(path.Join(user_dir, "media"), 0755)
// create Meta files
os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte(VERSION), 0644)

19
user.go
View File

@ -43,6 +43,11 @@ func (user User) WebmentionUrl() string {
return url
}
func (user User) MediaUrl() string {
url, _ := url.JoinPath(user.UrlPath(), "media")
return url
}
func (user User) PostDir() string {
return path.Join(user.Dir(), "public")
}
@ -51,6 +56,10 @@ func (user User) MetaDir() string {
return path.Join(user.Dir(), "meta")
}
func (user User) MediaDir() string {
return path.Join(user.Dir(), "media")
}
func (user User) ConfigFile() string {
return path.Join(user.MetaDir(), "config.yml")
}
@ -59,6 +68,16 @@ func (user User) Name() string {
return user.name
}
func (user User) AvatarUrl() string {
for _, ext := range []string{".jpg", ".jpeg", ".png", ".gif"} {
if fileExists(path.Join(user.MediaDir(), "avatar"+ext)) {
url, _ := url.JoinPath(user.MediaUrl(), "avatar"+ext)
return url
}
}
return ""
}
func (user User) Posts() ([]*Post, error) {
postFiles := listDir(path.Join(user.Dir(), "public"))
posts := make([]*Post, 0)

View File

@ -302,3 +302,18 @@ func TestPostsSortedByPublishingDateBrokenAtBottom(t *testing.T) {
t.Error("Wrong Id, Got: " + posts[1].Id())
}
}
func TestAvatarEmptyIfNotExist(t *testing.T) {
user := getTestUser()
if user.AvatarUrl() != "" {
t.Error("Avatar should be empty")
}
}
func TestAvatarSetIfFileExist(t *testing.T) {
user := getTestUser()
os.WriteFile(path.Join(user.MediaDir(), "avatar.png"), []byte("test"), 0644)
if user.AvatarUrl() == "" {
t.Error("Avatar should not be empty")
}
}