New dashboard idea (still not happy though)

This commit is contained in:
2016-11-22 12:34:59 +09:00
parent 4159525c25
commit 80506aa92e
18 changed files with 192 additions and 79 deletions

@ -24,6 +24,7 @@ component Content(content string)
component Navigation component Navigation
nav#navigation nav#navigation
NavigationButton("Dash", "/", "inbox") NavigationButton("Dash", "/", "inbox")
NavigationButton("Anime", "/anime", "television")
NavigationButton("Forum", "/forum", "comment") NavigationButton("Forum", "/forum", "comment")
NavigationButton("Genres", "/genres", "tags") NavigationButton("Genres", "/genres", "tags")

@ -12,7 +12,9 @@ import (
"github.com/animenotifier/notify.moe/pages/forums" "github.com/animenotifier/notify.moe/pages/forums"
"github.com/animenotifier/notify.moe/pages/genre" "github.com/animenotifier/notify.moe/pages/genre"
"github.com/animenotifier/notify.moe/pages/genres" "github.com/animenotifier/notify.moe/pages/genres"
"github.com/animenotifier/notify.moe/pages/posts"
"github.com/animenotifier/notify.moe/pages/profile" "github.com/animenotifier/notify.moe/pages/profile"
"github.com/animenotifier/notify.moe/pages/search"
"github.com/animenotifier/notify.moe/pages/threads" "github.com/animenotifier/notify.moe/pages/threads"
) )
@ -44,12 +46,14 @@ func main() {
} }
app.Ajax("/", dashboard.Get) app.Ajax("/", dashboard.Get)
app.Ajax("/anime", search.Get)
app.Ajax("/anime/:id", anime.Get) app.Ajax("/anime/:id", anime.Get)
app.Ajax("/genres", genres.Get) app.Ajax("/genres", genres.Get)
app.Ajax("/genres/:name", genre.Get) app.Ajax("/genres/:name", genre.Get)
app.Ajax("/forum", forums.Get) app.Ajax("/forum", forums.Get)
app.Ajax("/forum/:tag", forum.Get) app.Ajax("/forum/:tag", forum.Get)
app.Ajax("/threads/:id", threads.Get) app.Ajax("/threads/:id", threads.Get)
app.Ajax("/posts/:id", posts.Get)
app.Ajax("/user/:nick", profile.Get) app.Ajax("/user/:nick", profile.Get)
app.Run() app.Run()

@ -1,12 +1,18 @@
component Avatar(user *arn.User) component Avatar(user *arn.User)
a.user.ajax(href="/+" + user.Nick, title=user.Nick) a.user.ajax(href="/+" + user.Nick, title=user.Nick)
AvatarNoLink(user)
component AvatarNoLink(user *arn.User)
if user.Avatar != "" if user.Avatar != ""
if strings.Contains(user.Avatar, "gravatar.com") if strings.Contains(user.Avatar, "gravatar.com")
img.user-image(src=user.Avatar + "?s=100&r=x&d=mm", alt=user.Nick) img.user-image(src=user.Avatar + "?s=100&r=x&d=mm", alt=user.Nick)
else else
img.user-image(src=user.Avatar, alt=user.Nick) img.user-image(src=user.Avatar, alt=user.Nick)
else else
svg.user-image(width="50", height="50") SVGAvatar(50)
component SVGAvatar(size int)
svg.user-image(width=size, height=size, viewBox="0 0 50 50")
circle.head(cx="25", cy="19", r="10") circle.head(cx="25", cy="19", r="10")
circle.body(cx="25", cy="50", r="20") circle.body(cx="25", cy="50", r="20")
//- text(x="25", y="44", text-anchor="middle") TODO //- text(x="25", y="44", text-anchor="middle") TODO

43
mixins/Postable.pixy Normal file

@ -0,0 +1,43 @@
component Postable(post arn.Postable, viewUser *arn.User, highlightAuthorID string)
.post(data-highlight=post.Author().ID == highlightAuthorID)
.post-author
Avatar(post.Author())
//- if post.recipient && post.recipient.ID !== post.author.ID
//- a.user.post-recipient(href="/+" + post.recipient.nick, title=post.recipient.nick)
//- img.user-image(src=post.recipient.avatar ? (post.recipient.avatar + "?s=100&r=x&d=mm") : "/images/elements/no-gravatar.svg", alt=post.recipient.nick)
.post-content
div(id="render-" + post.ID())!= aero.Markdown(post.Text())
//- if user && user.ID === post.authorId
//- textarea.post-input.hidden(id="source-" + post.ID)= post.text
//- a.post-save.hidden(id="save-" + post.ID, onclick=`$.saveEdit("${type.toLowerCase()}", "${post.ID}")`)
//- i.fa.fa-save
//- span Save
.post-toolbar(id="toolbar-" + post.ID())
.spacer
.post-likes(id="likes-" + post.ID())= len(post.Likes())
//- if user != nil
//- if user.ID !== post.authorId
//- - var liked = post.likes && post.likes.indexOf(user.ID) !== -1
//- a.post-tool.post-like(id="like-" + post.ID, onclick=`$.like("${type.toLowerCase()}", "${post.ID}")`, title="Like", class=liked ? "hidden" : ")
//- i.fa.fa-thumbs-up.fa-fw
//- a.post-tool.post-unlike(id="unlike-" + post.ID, onclick=`$.unlike("${type.toLowerCase()}", "${post.ID}")`, title="Unlike", class=!liked ? "hidden" : ")
//- i.fa.fa-thumbs-down.fa-fw
//- if type === "Posts" || type === "Threads"
//- if user.ID === post.authorId
//- a.post-tool.post-edit(onclick=`$.edit("${post.ID}")`, title="Edit")
//- i.fa.fa-pencil.fa-fw
//- if post.Type() != "Thread"
a.post-tool.post-permalink.ajax(href=post.Link(), title="Permalink")
Icon("link")
//- if type === "Messages" && user && (user.ID === post.authorId || user.ID === post.recipientId)
//- a.post-tool.post-delete(onclick=`if(confirm("Do you really want to delete this ${typeSingular.toLowerCase()} from ${post.author.nick}?")) $.delete${typeSingular}("${post.ID}")`, title="Delete")
//- i.fa.fa-trash.fa-fw

@ -1,14 +0,0 @@
component Beta
section
header
h2 The future
p Shht! The next version of notify.moe is currently being built here.
hr
ul
li
a.ajax(href="/anime/21499") Sousei no Onmyouji
li
a.ajax(href="/anime/1000001") RWBY
li
a(href="/api/anime/1000001") RWBY (JSON API)

@ -1,11 +1,28 @@
package dashboard package dashboard
import ( import (
"sort"
"github.com/aerogo/aero" "github.com/aerogo/aero"
"github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/components" "github.com/animenotifier/notify.moe/components"
) )
const maxPosts = 6
// Get ... // Get ...
func Get(ctx *aero.Context) string { func Get(ctx *aero.Context) string {
return ctx.HTML(components.Dashboard()) posts, err := arn.GetPosts()
if err != nil {
return ctx.Error(500, "Error fetching posts")
}
sort.Sort(sort.Reverse(posts))
if len(posts) > maxPosts {
posts = posts[:maxPosts]
}
return ctx.HTML(components.Dashboard(posts))
} }

@ -1,4 +1,12 @@
component Dashboard component Dashboard(posts []*arn.Post)
section section
header header
h2 Dash h2 Dash
.dashboard-widget
each post in posts
a.dashboard-event.ui.ajax(href=post.Link())
.dashboard-event-author
AvatarNoLink(post.Author())
.dashboard-event-text
span= post.Thread().Title

@ -0,0 +1,23 @@
.dashboard-widget
display flex
flex-flow column
align-items center
.dashboard-event
display flex
flex-flow column wrap
margin-bottom 1rem
padding 0.75rem
width 100%
max-width 700px
.dashboard-event-author
display flex
justify-content center
width 100%
.dashboard-event-text
display flex
justify-content center
align-items center
width 100%

@ -21,9 +21,5 @@ func Get(ctx *aero.Context) string {
threads = threads[:threadsPerPage] threads = threads[:threadsPerPage]
} }
for _, thread := range threads {
thread.Init()
}
return ctx.HTML(components.Forum(tag, threads)) return ctx.HTML(components.Forum(tag, threads))
} }

@ -8,7 +8,7 @@ component Forum(tag string, threads []*arn.Thread)
component ThreadLink(thread *arn.Thread) component ThreadLink(thread *arn.Thread)
.thread-link(data-sticky=thread.Sticky) .thread-link(data-sticky=thread.Sticky)
.post-author.thread-author .post-author.thread-author
Avatar(thread.Author) Avatar(thread.Author())
.thread-content-container .thread-content-container
.post-content.thread-content .post-content.thread-content
if thread.Sticky if thread.Sticky

19
pages/posts/posts.go Normal file

@ -0,0 +1,19 @@
package posts
import (
"github.com/aerogo/aero"
"github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/components"
)
// Get ...
func Get(ctx *aero.Context) string {
id := ctx.Get("id")
post, err := arn.GetPost(id)
if err != nil {
return ctx.Error(404, "Post not found")
}
return ctx.HTML(components.Post(post))
}

5
pages/posts/posts.pixy Normal file

@ -0,0 +1,5 @@
component Post(post *arn.Post)
Postable(post.ToPostable(), nil, "")
.thread-source
a.ajax(href=post.Thread().Link())= post.Thread().Title

3
pages/posts/posts.styl Normal file

@ -0,0 +1,3 @@
.thread-source
font-size 0.9rem
text-align right !important

30
pages/search/search.go Normal file

@ -0,0 +1,30 @@
package search
import (
"github.com/aerogo/aero"
"github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/components"
)
// Get ...
func Get(ctx *aero.Context) string {
titleCount := 0
animeCount := 0
// let info: any = await bluebird.props({
// popular: arn.db.get('Cache', 'popularAnime'),
// stats: arn.db.get('Cache', 'animeStats')
// })
// return response.render({
// user,
// popularAnime: info.popular.anime,
// animeCount: info.stats.animeCount,
// titleCount: info.stats.titleCount,
// anime: null
// })
popular, _ := arn.GetPopularCache()
return ctx.HTML(components.Search(popular.Anime, titleCount, animeCount))
}

16
pages/search/search.pixy Normal file

@ -0,0 +1,16 @@
component Search(popularAnime []*arn.Anime, titleCount int, animeCount int)
h2 Anime
#search-container
input#search(type="text", placeholder="Search...", onkeyup="$.searchAnime();", onfocus="this.select();", disabled="disabled", data-count=titleCount, data-anime-count=animeCount)
#search-results-container
#search-results
if popularAnime != nil
h3.popular-title Popular
.popular-anime-list
each anime in popularAnime
a.popular-anime.ajax(href="/anime/" + toString(anime.ID), title=anime.Title.Romaji + " (" + arn.Plural(anime.Watching, "user") + " watching)")
img.anime-image.popular-anime-image(src=anime.Image, alt=anime.Title.Romaji)

2
pages/search/search.styl Normal file

@ -0,0 +1,2 @@
.popular-title
text-align center

@ -17,8 +17,6 @@ func Get(ctx *aero.Context) string {
return ctx.Error(404, "Thread not found") return ctx.Error(404, "Thread not found")
} }
thread.Author, _ = arn.GetUser(thread.AuthorID)
replies, filterErr := arn.FilterPosts(func(post *arn.Post) bool { replies, filterErr := arn.FilterPosts(func(post *arn.Post) bool {
return post.ThreadID == thread.ID return post.ThreadID == thread.ID
}) })

@ -3,51 +3,7 @@ component Thread(thread *arn.Thread, posts []*arn.Post)
h2.thread-title= thread.Title h2.thread-title= thread.Title
.posts .posts
Post(thread.ToPostable(), nil, "Threads", "Thread", thread.Author.ID) Postable(thread.ToPostable(), nil, thread.Author().ID)
each post in posts each post in posts
Post(post.ToPostable(), nil, "Posts", "Post", thread.Author.ID) Postable(post.ToPostable(), nil, thread.Author().ID)
component Post(post arn.Postable, viewUser *arn.User, postType string, postTypeSingular string, highlightAuthorID string)
.post(data-highlight=post.Author().ID == highlightAuthorID)
.post-author
Avatar(post.Author())
//- if post.recipient && post.recipient.ID !== post.author.ID
//- a.user.post-recipient(href="/+" + post.recipient.nick, title=post.recipient.nick)
//- img.user-image(src=post.recipient.avatar ? (post.recipient.avatar + "?s=100&r=x&d=mm") : "/images/elements/no-gravatar.svg", alt=post.recipient.nick)
.post-content
div(id="render-" + post.ID())!= aero.Markdown(post.Text())
//- if user && user.ID === post.authorId
//- textarea.post-input.hidden(id="source-" + post.ID)= post.text
//- a.post-save.hidden(id="save-" + post.ID, onclick=`$.saveEdit("${type.toLowerCase()}", "${post.ID}")`)
//- i.fa.fa-save
//- span Save
.post-toolbar(id="toolbar-" + post.ID())
.spacer
.post-likes(id="likes-" + post.ID())= len(post.Likes())
//- if user != nil
//- if user.ID !== post.authorId
//- - var liked = post.likes && post.likes.indexOf(user.ID) !== -1
//- a.post-tool.post-like(id="like-" + post.ID, onclick=`$.like("${type.toLowerCase()}", "${post.ID}")`, title="Like", class=liked ? "hidden" : ")
//- i.fa.fa-thumbs-up.fa-fw
//- a.post-tool.post-unlike(id="unlike-" + post.ID, onclick=`$.unlike("${type.toLowerCase()}", "${post.ID}")`, title="Unlike", class=!liked ? "hidden" : ")
//- i.fa.fa-thumbs-down.fa-fw
//- if type === "Posts" || type === "Threads"
//- if user.ID === post.authorId
//- a.post-tool.post-edit(onclick=`$.edit("${post.ID}")`, title="Edit")
//- i.fa.fa-pencil.fa-fw
//- if type !== "Threads"
//- a.post-tool.post-permalink.ajax(href="/" + type.toLowerCase() + "/" + post.ID, title="Permalink")
//- i.fa.fa-link.fa-fw
//- if type === "Messages" && user && (user.ID === post.authorId || user.ID === post.recipientId)
//- a.post-tool.post-delete(onclick=`if(confirm("Do you really want to delete this ${typeSingular.toLowerCase()} from ${post.author.nick}?")) $.delete${typeSingular}("${post.ID}")`, title="Delete")
//- i.fa.fa-trash.fa-fw