✨ Added the list of quotes sorted by last and best with a correct design.
The design has been verified to be responsive and compatible with the dark theme
This commit is contained in:
66
pages/quotes/best.go
Normal file
66
pages/quotes/best.go
Normal file
@ -0,0 +1,66 @@
|
||||
package quotes
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/aerogo/aero"
|
||||
"github.com/animenotifier/arn"
|
||||
"github.com/animenotifier/notify.moe/components"
|
||||
"github.com/animenotifier/notify.moe/utils"
|
||||
)
|
||||
|
||||
// Best renders the quotes page ordered by the most favorites first.
|
||||
func Best(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
|
||||
quotes := arn.FilterQuotes(func(track *arn.Quote) bool {
|
||||
return !track.IsDraft && len(track.Description) > 0
|
||||
})
|
||||
|
||||
arn.SortQuotesPopularFirst(quotes)
|
||||
|
||||
if len(quotes) > maxQuotes {
|
||||
quotes = quotes[:maxQuotes]
|
||||
}
|
||||
|
||||
return ctx.HTML(components.Quotes(quotes, maxQuotes, user))
|
||||
}
|
||||
|
||||
// BestFrom renders the quotes from the given index.
|
||||
func BestFrom(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
index, err := ctx.GetInt("index")
|
||||
|
||||
if err != nil {
|
||||
return ctx.Error(http.StatusBadRequest, "Invalid start index", err)
|
||||
}
|
||||
|
||||
allQuotes := arn.FilterQuotes(func(track *arn.Quote) bool {
|
||||
return !track.IsDraft && len(track.Description) > 0
|
||||
})
|
||||
|
||||
if index < 0 || index >= len(allQuotes) {
|
||||
return ctx.Error(http.StatusBadRequest, "Invalid start index (maximum is "+strconv.Itoa(len(allQuotes))+")", nil)
|
||||
}
|
||||
|
||||
arn.SortQuotesPopularFirst(allQuotes)
|
||||
|
||||
quotes := allQuotes[index:]
|
||||
|
||||
if len(quotes) > maxQuotes {
|
||||
quotes = quotes[:maxQuotes]
|
||||
}
|
||||
|
||||
nextIndex := index + maxQuotes
|
||||
|
||||
if nextIndex >= len(allQuotes) {
|
||||
// End of data - no more scrolling
|
||||
ctx.Response().Header().Set("X-LoadMore-Index", "-1")
|
||||
} else {
|
||||
// Send the index for the next request
|
||||
ctx.Response().Header().Set("X-LoadMore-Index", strconv.Itoa(nextIndex))
|
||||
}
|
||||
|
||||
return ctx.HTML(components.QuotesScrollable(quotes, user))
|
||||
}
|
@ -5,12 +5,62 @@ import (
|
||||
"github.com/animenotifier/arn"
|
||||
"github.com/animenotifier/notify.moe/components"
|
||||
"github.com/animenotifier/notify.moe/utils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Get renders the quotes page.
|
||||
func Get(ctx *aero.Context) string {
|
||||
const maxQuotes = 12
|
||||
|
||||
// Latest renders the quotes page.
|
||||
func Latest(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
|
||||
quotes := arn.AllQuotes()
|
||||
return ctx.HTML(components.Quotes(quotes, user))
|
||||
quotes := arn.FilterQuotes(func(track *arn.Quote) bool {
|
||||
return !track.IsDraft && len(track.Description) > 0
|
||||
})
|
||||
|
||||
arn.SortQuotesLatestFirst(quotes)
|
||||
|
||||
if len(quotes) > maxQuotes {
|
||||
quotes = quotes[:maxQuotes]
|
||||
}
|
||||
return ctx.HTML(components.Quotes(quotes, maxQuotes, user))
|
||||
}
|
||||
|
||||
// LatestFrom renders the quotes from the given index.
|
||||
func LatestFrom(ctx *aero.Context) string {
|
||||
user := utils.GetUser(ctx)
|
||||
index, err := ctx.GetInt("index")
|
||||
|
||||
if err != nil {
|
||||
return ctx.Error(http.StatusBadRequest, "Invalid start index", err)
|
||||
}
|
||||
|
||||
allQuotes := arn.FilterQuotes(func(track *arn.Quote) bool {
|
||||
return !track.IsDraft && len(track.Description) > 0
|
||||
})
|
||||
|
||||
if index < 0 || index >= len(allQuotes) {
|
||||
return ctx.Error(http.StatusBadRequest, "Invalid start index (maximum is "+strconv.Itoa(len(allQuotes))+")", nil)
|
||||
}
|
||||
|
||||
arn.SortQuotesLatestFirst(allQuotes)
|
||||
|
||||
quotes := allQuotes[index:]
|
||||
|
||||
if len(quotes) > maxQuotes {
|
||||
quotes = quotes[:maxQuotes]
|
||||
}
|
||||
|
||||
nextIndex := index + maxQuotes
|
||||
|
||||
if nextIndex >= len(allQuotes) {
|
||||
// End of data - no more scrolling
|
||||
ctx.Response().Header().Set("X-LoadMore-Index", "-1")
|
||||
} else {
|
||||
// Send the index for the next request
|
||||
ctx.Response().Header().Set("X-LoadMore-Index", strconv.Itoa(nextIndex))
|
||||
}
|
||||
|
||||
return ctx.HTML(components.QuotesScrollable(quotes, user))
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
component Quotes(quotes []*arn.Quote, user *arn.User)
|
||||
component Quotes(quotes []*arn.Quote, quotesPerPage int, user *arn.User)
|
||||
h1.page-title Quotes
|
||||
|
||||
QuotesTabs
|
||||
|
||||
.corner-buttons
|
||||
if user != nil
|
||||
if user.DraftIndex().QuoteID == ""
|
||||
@ -12,6 +14,18 @@ component Quotes(quotes []*arn.Quote, user *arn.User)
|
||||
Icon("pencil")
|
||||
span Edit draft
|
||||
|
||||
ul
|
||||
each quote in quotes
|
||||
li= quote.Description
|
||||
#load-more-target.quotes
|
||||
QuotesScrollable(quotes, user)
|
||||
|
||||
if len(quotes) == quotesPerPage
|
||||
.buttons
|
||||
LoadMore(quotesPerPage)
|
||||
|
||||
component QuotesScrollable(quotes []*arn.Quote, user *arn.User)
|
||||
each quote in quotes
|
||||
Quote(quote)
|
||||
|
||||
component QuotesTabs
|
||||
.tabs
|
||||
Tab("Latest", "quote-left", "/quotes")
|
||||
Tab("Best", "heart", "/quotes/best")
|
87
pages/quotes/quotes.scarlet
Normal file
87
pages/quotes/quotes.scarlet
Normal file
@ -0,0 +1,87 @@
|
||||
.quotes
|
||||
horizontal-wrap
|
||||
justify-content space-around
|
||||
|
||||
.quote
|
||||
vertical
|
||||
flex 1
|
||||
flex-basis 500px
|
||||
padding 1rem
|
||||
|
||||
.quote-content
|
||||
vertical
|
||||
border-radius 3px
|
||||
border-left 5px solid quote-side-border-color
|
||||
overflow hidden
|
||||
box-shadow shadow-light
|
||||
align-items stretch
|
||||
align-content stretch
|
||||
|
||||
.quote-character
|
||||
horizontal
|
||||
align-self flex-end
|
||||
align-items baseline
|
||||
justify-content space-around
|
||||
padding 0 1em 1em 0
|
||||
|
||||
span
|
||||
opacity 0.65
|
||||
|
||||
a
|
||||
display inline
|
||||
margin-left 0.5em
|
||||
|
||||
|
||||
.quote-footer
|
||||
text-align center
|
||||
margin-bottom 1rem
|
||||
margin-top 0.4rem
|
||||
font-size 0.9em
|
||||
|
||||
span
|
||||
opacity 0.65
|
||||
|
||||
.quotation
|
||||
height 100%
|
||||
display flex
|
||||
flex-grow 1
|
||||
align-items stretch
|
||||
align-content stretch
|
||||
|
||||
blockquote
|
||||
flex-grow 1
|
||||
padding 1em
|
||||
|
||||
p
|
||||
line-height 2em
|
||||
|
||||
q
|
||||
quotes "\201C""\201D"
|
||||
|
||||
:before
|
||||
color quote-color
|
||||
content open-quote
|
||||
font-size 4em
|
||||
line-height 0.1em
|
||||
margin-right 0.25em
|
||||
vertical-align -0.4em
|
||||
|
||||
:after
|
||||
color quote-color
|
||||
content close-quote
|
||||
font-size 4em
|
||||
line-height 0.1em
|
||||
margin-left 0.25em
|
||||
vertical-align -0.4em
|
||||
|
||||
|
||||
.character
|
||||
display none !important
|
||||
|
||||
> 800px
|
||||
.character
|
||||
margin 0.5em 0 0 0.5em !important
|
||||
display block !important
|
||||
|
||||
.quote-character a
|
||||
display none
|
Reference in New Issue
Block a user