New dashboard idea (still not happy though)

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

View File

@ -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")

View File

@ -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()

View File

@ -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)
if user.Avatar != "" AvatarNoLink(user)
if strings.Contains(user.Avatar, "gravatar.com")
img.user-image(src=user.Avatar + "?s=100&r=x&d=mm", alt=user.Nick) component AvatarNoLink(user *arn.User)
else if user.Avatar != ""
img.user-image(src=user.Avatar, alt=user.Nick) if strings.Contains(user.Avatar, "gravatar.com")
img.user-image(src=user.Avatar + "?s=100&r=x&d=mm", alt=user.Nick)
else else
svg.user-image(width="50", height="50") img.user-image(src=user.Avatar, alt=user.Nick)
circle.head(cx="25", cy="19", r="10") else
circle.body(cx="25", cy="50", r="20") SVGAvatar(50)
//- text(x="25", y="44", text-anchor="middle") TODO
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.body(cx="25", cy="50", r="20")
//- text(x="25", y="44", text-anchor="middle") TODO

43
mixins/Postable.pixy Normal file
View 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

View File

@ -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)

View File

@ -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))
} }

View File

@ -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

View File

@ -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%

View File

@ -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))
} }

View File

@ -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
View 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
View 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
View File

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

30
pages/search/search.go Normal file
View 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
View 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
View File

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

View File

@ -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
}) })

View File

@ -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