diff --git a/api.go b/api.go index ca3a0625..608f84b2 100644 --- a/api.go +++ b/api.go @@ -17,7 +17,7 @@ func init() { // } // sort.Strings(titles) - // return ctx.Text(toString(len(titles)) + "\n\n" + strings.Join(titles, "\n")) + // return ctx.Error(toString(len(titles)) + "\n\n" + strings.Join(titles, "\n")) // }) app.Get("/api/anime/:id", func(ctx *aero.Context) string { @@ -25,7 +25,7 @@ func init() { anime, err := arn.GetAnime(id) if err != nil { - return ctx.Text("Anime not found") + return ctx.Error(404, "Anime not found") } return ctx.JSON(anime) @@ -36,7 +36,7 @@ func init() { user, err := arn.GetUserByNick(nick) if err != nil { - return ctx.Text("User not found") + return ctx.Error(404, "User not found") } return ctx.JSON(user) @@ -47,7 +47,7 @@ func init() { thread, err := arn.GetThread(id) if err != nil { - return ctx.Text("Thread not found") + return ctx.Error(404, "Thread not found") } return ctx.JSON(thread) diff --git a/main.go b/main.go index 864f2278..eb9241c7 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "github.com/aerogo/aero" + "github.com/animenotifier/arn" "github.com/animenotifier/notify.moe/components" "github.com/animenotifier/notify.moe/pages/anime" "github.com/animenotifier/notify.moe/pages/dashboard" @@ -11,6 +12,7 @@ import ( "github.com/animenotifier/notify.moe/pages/forums" "github.com/animenotifier/notify.moe/pages/genre" "github.com/animenotifier/notify.moe/pages/genres" + "github.com/animenotifier/notify.moe/pages/profile" "github.com/animenotifier/notify.moe/pages/threads" ) @@ -19,6 +21,12 @@ var app = aero.New() func main() { app.SetStyle(components.BundledCSS) + user, _ := arn.GetUserByNick("Akyoto") + user.CoverImage.URL = "http://i.imgur.com/6cJrxzx.jpg" + user.CoverImage.Position.X = "50%" + user.CoverImage.Position.Y = "85%" + user.Save() + scripts, _ := ioutil.ReadFile("temp/scripts.js") js := string(scripts) @@ -42,6 +50,7 @@ func main() { app.Ajax("/forum", forums.Get) app.Ajax("/forum/:tag", forum.Get) app.Ajax("/threads/:id", threads.Get) + app.Ajax("/user/:nick", profile.Get) app.Run() } diff --git a/mixins/ProfileImage.pixy b/mixins/ProfileImage.pixy new file mode 100644 index 00000000..6f0a60f6 --- /dev/null +++ b/mixins/ProfileImage.pixy @@ -0,0 +1,5 @@ +component ProfileImage(user *arn.User) + if user.Avatar != "" + img.profile-image(src=user.Avatar + "?s=640&r=x&d=mm", alt="Profile image") + else + img.profile-image(src="/images/elements/no-gravatar.svg", alt="Profile image") \ No newline at end of file diff --git a/pages/anime/anime.go b/pages/anime/anime.go index c8ff2661..96fc510d 100644 --- a/pages/anime/anime.go +++ b/pages/anime/anime.go @@ -12,7 +12,7 @@ func Get(ctx *aero.Context) string { anime, err := arn.GetAnime(id) if err != nil { - return ctx.Text("Anime not found") + return ctx.Error(404, "Anime not found") } return ctx.HTML(components.Anime(anime)) diff --git a/pages/genres/genres.go b/pages/genres/genres.go index 310a4b6f..c4077dc4 100644 --- a/pages/genres/genres.go +++ b/pages/genres/genres.go @@ -13,6 +13,11 @@ func Get(ctx *aero.Context) string { var genres []*arn.Genre for _, genreName := range arn.Genres { + // Skip this genre because it doesn't get processed in the background jobs + if genreName == "Hentai" { + continue + } + genre, err := arn.GetGenre(arn.GetGenreIDByName(genreName)) if err == nil { diff --git a/pages/profile/profile.go b/pages/profile/profile.go new file mode 100644 index 00000000..31cca56f --- /dev/null +++ b/pages/profile/profile.go @@ -0,0 +1,19 @@ +package profile + +import ( + "github.com/aerogo/aero" + "github.com/animenotifier/arn" + "github.com/animenotifier/notify.moe/components" +) + +// Get ... +func Get(ctx *aero.Context) string { + nick := ctx.Get("nick") + user, err := arn.GetUserByNick(nick) + + if err != nil { + return ctx.Error(404, "User not found") + } + + return ctx.HTML(components.Profile(user, nil)) +} diff --git a/pages/profile/profile.pixy b/pages/profile/profile.pixy new file mode 100644 index 00000000..47cd7a3a --- /dev/null +++ b/pages/profile/profile.pixy @@ -0,0 +1,63 @@ +component Profile(viewUser *arn.User, user *arn.User) + .profile + .profile-cover(style=viewUser.CoverImageStyle()) + + .image-container + ProfileImage(viewUser) + + .intro-container + h2#nick= viewUser.Nick + + if viewUser.Tagline != "" + p.profile-field.tagline + Icon("comment") + span.tagline= viewUser.Tagline + else + p.profile-field.tagline + Icon("comment") + span.tagline No tagline yet. + + //- if user != nil && viewUser.website + //- p.profile-field.website + //- Icon("home") + //- a(href=viewUser.website.startsWith('http') ? viewUser.website : 'http://' + viewUser.website, target='_blank', rel='nofollow')= viewUser.website.replace('http://', '').replace('https://', '') + + //- if user != nil && (user.osu || user.osuDetails) && viewUser.osuDetails && viewUser.osuDetails.pp >= 1000 + //- p.profile-field.osu(title='osu! performance points') + //- i.fa.fa-trophy + //- span= parseInt(viewUser.osuDetails.pp) + ' pp' + + //- if viewUser.dataEditCount + //- p.profile-field.editor-contribution(title="Anime data modifications") + //- Icon("edit") + //- span= viewUser.dataEditCount + + if viewUser.Registered != "" + p.profile-field.registration-date(title="Member since") + Icon("calendar") + //- span= time.Parse(time.RFC3339, viewUser.Registered) + span= viewUser.Registered[:4] + //- span= monthNames[joined.getMonth()] + ' ' + joined.getFullYear() + + if viewUser.Role != "" + p.profile-field.role + Icon("rocket") + span= arn.Capitalize(viewUser.Role) + + //- .a + //- h3 Category + + //- .a + //- h3 Category + + //- .a + //- h3 Category + + //- .a + //- h3 Category + + //- .a + //- h3 Category + + //- .a + //- h3 Category \ No newline at end of file diff --git a/pages/profile/profile.styl b/pages/profile/profile.styl new file mode 100644 index 00000000..d3c8b95c --- /dev/null +++ b/pages/profile/profile.styl @@ -0,0 +1,165 @@ +.profile + position relative + left contentPadding * -1 + top contentPadding * -1 + min-width 100% + padding contentPadding + box-sizing content-box + + color white + text-shadow 0px 0px 1px rgba(0, 0, 0, 0.1) + + transition all transitionSpeed ease + animation-name appear + animation-duration transitionSpeed + + &:hover + .profile-cover + filter brightness(28%) + +.profile-cover + position absolute + left 0 + top 0 + width 100% + height 100% + z-index -1 + background-size cover + + filter brightness(35%) + transition filter transitionSpeed ease + +@keyframes appear + 0% + transform rotateX(90deg) + filter opacity(0) saturate(0) blur(10px) + 100% + transform rotateX(0) + filter opacity(1) saturate(1) blur(0) + +.profile-image + border-radius 3px + width 320px + height 320px !important + margin contentPadding + object-fit cover + +#anime-list-container + flex 1.5 + +.image-container + float left + width auto + +.intro-container + float left + width auto + display flex + flex-flow column + align-items center + padding 1.5em + max-width 900px + +.user-actions + float right + display flex + flex-flow row + justify-content center + +.user-action + max-width 250px + +#nick + text-align left + margin-top 0 + margin-bottom 0 + +.profile-field + margin-bottom 0.2em + +.location + // ... + +.role + opacity 0.6 + +.list-provider-username + margin-top 0 + margin-bottom 0 + font-size 0.9em + +.main + // ... + +.alternative + opacity 0.4 + +.report-bug-hint + // + +.loading-message + margin 0 auto + text-align center + opacity 0.4 + +#embedded-footer + position fixed + bottom 4em + right calc(16px + 1em) + text-align right + z-index 1 + font-size 0.9em + display flex + flex-flow row + + .user + display inline-block + width auto + height auto + margin-right 1em + +.embedded-footer-info + display flex + flex-flow column + +.embedded-footer-nick + text-align left + opacity 0.5 + +.embedded-footer-separator + opacity 0.2 + +.appear + animation-name appear-animation + animation-duration 1s + +@keyframes appear-animation + 0% + opacity 0 + 100% + opacity 1 + +@media only screen and (max-width: 900px) + .intro-container + margin 1em 0 + padding 0 + width 100% + text-align center !important + + #anime-list-container + .image-container + .user-actions + width 100% + + #nick + .profile-field + width 100% + text-align center + +@media only screen and (min-width: 900px) + #posts + margin-left 0.5em + +@media only screen and (max-width: 800px) + .airing-date-prefix + display none \ No newline at end of file diff --git a/pages/threads/threads.go b/pages/threads/threads.go index 39c77832..8cd83f89 100644 --- a/pages/threads/threads.go +++ b/pages/threads/threads.go @@ -14,7 +14,7 @@ func Get(ctx *aero.Context) string { thread, err := arn.GetThread(id) if err != nil { - return ctx.Text("Thread not found") + return ctx.Error(404, "Thread not found") } thread.Author, _ = arn.GetUser(thread.AuthorID) @@ -26,7 +26,7 @@ func Get(ctx *aero.Context) string { sort.Sort(replies) if filterErr != nil { - return ctx.Text("Error fetching thread replies") + return ctx.Error(500, "Error fetching thread replies") } return ctx.HTML(components.Thread(thread, replies)) diff --git a/rewrite.go b/rewrite.go new file mode 100644 index 00000000..7b2f13f6 --- /dev/null +++ b/rewrite.go @@ -0,0 +1,29 @@ +package main + +import ( + "bytes" + + "github.com/valyala/fasthttp" +) + +func init() { + plusRoute := []byte("/+") + plusRouteAjax := []byte("/_/+") + + // This will rewrite /+UserName requests to /user/UserName + app.Rewrite(func(ctx *fasthttp.RequestCtx) { + requestURI := ctx.RequestURI() + + if bytes.HasPrefix(requestURI, plusRoute) { + newURI := []byte("/user/") + userName := requestURI[2:] + newURI = append(newURI, userName...) + ctx.Request.SetRequestURIBytes(newURI) + } else if bytes.HasPrefix(requestURI, plusRouteAjax) { + newURI := []byte("/_/user/") + userName := requestURI[4:] + newURI = append(newURI, userName...) + ctx.Request.SetRequestURIBytes(newURI) + } + }) +} diff --git a/styles/base.styl b/styles/base.styl index 6eff5727..9f6f6b8b 100644 --- a/styles/base.styl +++ b/styles/base.styl @@ -3,13 +3,11 @@ html body font-family "Ubuntu", "Trebuchet MS", sans-serif - font-size 1.05em + font-size 1.05rem tab-size 4 overflow-x hidden overflow-y hidden height 100% - -webkit-font-smoothing antialiased - -moz-osx-font-smoothing grayscale a text-decoration none diff --git a/styles/config.styl b/styles/config.styl index d6d7639e..5c767104 100644 --- a/styles/config.styl +++ b/styles/config.styl @@ -13,6 +13,7 @@ outlineShadowMedium = 0 0 6px alpha(black, 0.13) outlineShadowHeavy = 0 0 6px alpha(black, 0.6) transitionSpeed = 290ms fadeSpeed = 200ms +contentPadding = 1.5rem uiElement() border uiBorder diff --git a/styles/forms.styl b/styles/forms.styl index ab611c40..bc8ebece 100644 --- a/styles/forms.styl +++ b/styles/forms.styl @@ -6,10 +6,10 @@ input[type="password"] input[type="url"] input[type="number"] button - font-family "Ubuntu", sans-serif - font-size 1em + font-family inherit + font-size 1rem border-radius 3px - transition all 0.5s ease + transition all transitionSpeed ease margin 0 0 10px padding 0.4em 0.8em width calc(100% - 1.6em) @@ -23,7 +23,7 @@ button input[type="submit"] button .button - font-family "Ubuntu", sans-serif + font-family inherit font-size 1em color black padding 0.5em 2em @@ -41,7 +41,7 @@ textarea border-radius 3px padding 0.2em 0.4em font-size 1em - font-family "Open Sans", Ubuntu, sans-serif + font-family inherit line-height 1.7em outline none resize vertical diff --git a/styles/layout.styl b/styles/layout.styl index 1d1134e0..5dc6f7b4 100644 --- a/styles/layout.styl +++ b/styles/layout.styl @@ -62,16 +62,15 @@ background-color transparent #content - float left width 100% height 100% min-height 100% - padding 1.5em + padding contentPadding line-height 1.7em text-align center - box-sizing border-box + display flex + flex-flow column & > div - float left width 100% .header-logged-in diff --git a/styles/navigation.styl b/styles/navigation.styl index 149028aa..579257a5 100644 --- a/styles/navigation.styl +++ b/styles/navigation.styl @@ -1,10 +1,8 @@ #navigation - float left - width 100% - margin 0 auto width 100% height 100% - padding 0 1.5em + padding 0 contentPadding + margin 0 auto z-index 0 box-sizing border-box diff --git a/styles/reset.styl b/styles/reset.styl index bcd83de7..7908532a 100644 --- a/styles/reset.styl +++ b/styles/reset.styl @@ -30,6 +30,8 @@ footer, header, hgroup, menu, nav, section body line-height 1 + -webkit-font-smoothing antialiased + -moz-osx-font-smoothing grayscale ol, ul list-style none