This commit is contained in:
Eduard Urbach 2017-07-22 15:04:54 +02:00
parent e9e0aa89eb
commit 16cbd5167f
29 changed files with 262 additions and 204 deletions

View File

@ -20,14 +20,15 @@ component Layout(app *aero.Application, ctx *aero.Context, user *arn.User, openG
link(rel="manifest", href="/manifest.json") link(rel="manifest", href="/manifest.json")
body body
#container(class=utils.GetContainerClass(ctx)) #container(class=utils.GetContainerClass(ctx))
#header //- #header
Navigation(user) //- Navigation(user)
#content-container #columns
main#content.fade!= content aside#sidebar
LoadingAnimation Sidebar(user)
StatusMessage #content-container
aside#sidebar main#content.fade!= content
Sidebar(user) LoadingAnimation
StatusMessage
if user != nil if user != nil
#user(data-id=user.ID) #user(data-id=user.ID)
script(src="/scripts") script(src="/scripts")

View File

@ -10,19 +10,21 @@ import (
"github.com/animenotifier/notify.moe/layout" "github.com/animenotifier/notify.moe/layout"
"github.com/animenotifier/notify.moe/middleware" "github.com/animenotifier/notify.moe/middleware"
"github.com/animenotifier/notify.moe/pages/admin" "github.com/animenotifier/notify.moe/pages/admin"
"github.com/animenotifier/notify.moe/pages/amvs"
"github.com/animenotifier/notify.moe/pages/anime" "github.com/animenotifier/notify.moe/pages/anime"
"github.com/animenotifier/notify.moe/pages/animelist" "github.com/animenotifier/notify.moe/pages/animelist"
"github.com/animenotifier/notify.moe/pages/animelistitem" "github.com/animenotifier/notify.moe/pages/animelistitem"
"github.com/animenotifier/notify.moe/pages/apiview" "github.com/animenotifier/notify.moe/pages/apiview"
"github.com/animenotifier/notify.moe/pages/artworks"
"github.com/animenotifier/notify.moe/pages/best" "github.com/animenotifier/notify.moe/pages/best"
"github.com/animenotifier/notify.moe/pages/character" "github.com/animenotifier/notify.moe/pages/character"
"github.com/animenotifier/notify.moe/pages/dashboard"
"github.com/animenotifier/notify.moe/pages/editanime" "github.com/animenotifier/notify.moe/pages/editanime"
"github.com/animenotifier/notify.moe/pages/editor" "github.com/animenotifier/notify.moe/pages/editor"
"github.com/animenotifier/notify.moe/pages/embed" "github.com/animenotifier/notify.moe/pages/embed"
"github.com/animenotifier/notify.moe/pages/explore" "github.com/animenotifier/notify.moe/pages/explore"
"github.com/animenotifier/notify.moe/pages/forum" "github.com/animenotifier/notify.moe/pages/forum"
"github.com/animenotifier/notify.moe/pages/forums" "github.com/animenotifier/notify.moe/pages/forums"
"github.com/animenotifier/notify.moe/pages/home"
"github.com/animenotifier/notify.moe/pages/listimport" "github.com/animenotifier/notify.moe/pages/listimport"
"github.com/animenotifier/notify.moe/pages/listimport/listimportanilist" "github.com/animenotifier/notify.moe/pages/listimport/listimportanilist"
"github.com/animenotifier/notify.moe/pages/listimport/listimportkitsu" "github.com/animenotifier/notify.moe/pages/listimport/listimportkitsu"
@ -68,7 +70,7 @@ func configure(app *aero.Application) *aero.Application {
app.Layout = layout.Render app.Layout = layout.Render
// Ajax routes // Ajax routes
app.Ajax("/", dashboard.Get) app.Ajax("/", home.Get)
app.Ajax("/anime/:id", anime.Get) app.Ajax("/anime/:id", anime.Get)
app.Ajax("/anime/:id/edit", editanime.Get) app.Ajax("/anime/:id/edit", editanime.Get)
app.Ajax("/api", apiview.Get) app.Ajax("/api", apiview.Get)
@ -84,6 +86,8 @@ func configure(app *aero.Application) *aero.Application {
app.Ajax("/new/soundtrack", newsoundtrack.Get) app.Ajax("/new/soundtrack", newsoundtrack.Get)
app.Ajax("/settings", settings.Get) app.Ajax("/settings", settings.Get)
app.Ajax("/soundtracks", music.Get) app.Ajax("/soundtracks", music.Get)
app.Ajax("/artworks", artworks.Get)
app.Ajax("/amvs", amvs.Get)
app.Ajax("/users", users.Active) app.Ajax("/users", users.Active)
app.Ajax("/users/osu", users.Osu) app.Ajax("/users/osu", users.Osu)
app.Ajax("/users/staff", users.Staff) app.Ajax("/users/staff", users.Staff)

View File

@ -1,5 +1,5 @@
component ForumTags component ForumTags
.buttons.tabs .tabs
ForumTag("All", "", "list") ForumTag("All", "", "list")
ForumTag("General", "general", "list") ForumTag("General", "general", "list")
ForumTag("News", "news", "list") ForumTag("News", "news", "list")
@ -9,6 +9,6 @@ component ForumTags
ForumTag("Bugs", "bug", "list") ForumTag("Bugs", "bug", "list")
component ForumTag(title string, category string, icon string) component ForumTag(title string, category string, icon string)
a.button.tab.action(href=strings.TrimSuffix("/forum/" + category, "/"), data-action="diff", data-trigger="click") a.tab.action(href=strings.TrimSuffix("/forum/" + category, "/"), data-action="diff", data-trigger="click")
Icon(arn.GetForumIcon(category)) Icon(arn.GetForumIcon(category))
span.tab-text= title span.tab-text= title

View File

@ -33,28 +33,28 @@ component LoggedInMenu(user *arn.User)
Icon("bars") Icon("bars")
span.navigation-text Menu span.navigation-text Menu
.extra-navigation //- .extra-navigation
NavigationButton("Profile", "/+", "user") //- NavigationButton("Profile", "/+", "user")
.extra-navigation //- .extra-navigation
NavigationButton("Forum", "/forum", "comment") //- NavigationButton("Forum", "/forum", "comment")
//- .extra-navigation //- .extra-navigation
//- NavigationButton("Soundtracks", "/soundtracks", "headphones") //- NavigationButton("Soundtracks", "/soundtracks", "headphones")
FuzzySearch FuzzySearch
.extra-navigation //- .extra-navigation
NavigationButton("Users", "/users", "globe") //- NavigationButton("Users", "/users", "globe")
.extra-navigation //- .extra-navigation
NavigationButton("Explore", "/explore", "th") //- NavigationButton("Explore", "/explore", "th")
//- .extra-navigation //- .extra-navigation
//- NavigationButton("Statistics", "/statistics", "pie-chart") //- NavigationButton("Statistics", "/statistics", "pie-chart")
.hide-landscape //- .hide-landscape
NavigationButton("Settings", "/settings", "cog") //- NavigationButton("Settings", "/settings", "cog")
//- .extra-navigation.hide-landscape //- .extra-navigation.hide-landscape
//- NavigationButtonNoAJAX("Logout", "/logout", "sign-out") //- NavigationButtonNoAJAX("Logout", "/logout", "sign-out")

View File

@ -8,7 +8,9 @@ component Sidebar(user *arn.User)
SidebarButton("Home", "/", "home") SidebarButton("Home", "/", "home")
SidebarButton("Forum", "/forum", "comment") SidebarButton("Forum", "/forum", "comment")
SidebarButton("Explore", "/explore", "th") SidebarButton("Explore", "/explore", "th")
SidebarButton("Artworks", "/artworks", "paint-brush")
SidebarButton("Soundtracks", "/soundtracks", "headphones") SidebarButton("Soundtracks", "/soundtracks", "headphones")
SidebarButton("AMVs", "/amvs", "video-camera")
SidebarButton("Users", "/users", "globe") SidebarButton("Users", "/users", "globe")
if user != nil if user != nil
@ -17,6 +19,8 @@ component Sidebar(user *arn.User)
SidebarButton("Settings", "/settings", "cog") SidebarButton("Settings", "/settings", "cog")
.spacer
SidebarButton("Help", "/thread/I3MMiOtzR", "question") SidebarButton("Help", "/thread/I3MMiOtzR", "question")
if user != nil if user != nil

21
mixins/StatusTabs.pixy Normal file
View File

@ -0,0 +1,21 @@
component StatusTabs(urlPrefix string)
.tabs.status-tabs
a.tab.status-tab.action(href=urlPrefix + "/watching", data-action="diff", data-trigger="click")
Icon("play")
span.tab-text Watching
a.tab.status-tab.action(href=urlPrefix + "/completed", data-action="diff", data-trigger="click")
Icon("check")
span.tab-text Completed
a.tab.status-tab.action(href=urlPrefix + "/planned", data-action="diff", data-trigger="click")
Icon("forward")
span.tab-text Planned
a.tab.status-tab.action(href=urlPrefix + "/hold", data-action="diff", data-trigger="click")
Icon("pause")
span.tab-text On Hold
a.tab.status-tab.action(href=urlPrefix + "/dropped", data-action="diff", data-trigger="click")
Icon("stop")
span.tab-text Dropped

10
pages/amvs/amvs.go Normal file
View File

@ -0,0 +1,10 @@
package amvs
import (
"github.com/aerogo/aero"
)
// Get AMVs.
func Get(ctx *aero.Context) string {
return ctx.HTML("Coming soon™.")
}

View File

@ -14,7 +14,7 @@
align-items flex-start align-items flex-start
.anime-cover-image .anime-cover-image
width 230px width 142px
height auto height auto
border-radius 3px border-radius 3px

View File

@ -28,5 +28,5 @@ func Get(ctx *aero.Context) string {
animeList.PrefetchAnime() animeList.PrefetchAnime()
animeList.Sort() animeList.Sort()
return ctx.HTML(components.AnimeLists(animeList.SplitByStatus(), animeList.User(), user, ctx.URI())) return ctx.HTML(components.ProfileAnimeLists(animeList.SplitByStatus(), animeList.User(), user, ctx.URI()))
} }

View File

@ -1,8 +1,15 @@
component AnimeLists(animeLists map[string]*arn.AnimeList, viewUser *arn.User, user *arn.User, uri string) component ProfileAnimeLists(animeLists map[string]*arn.AnimeList, viewUser *arn.User, user *arn.User, uri string)
ProfileHeader(viewUser, user, uri) ProfileHeader(viewUser, user, uri)
h1.page-title.anime-list-owner= viewUser.Nick + "'s collection" h1.page-title.anime-list-owner= viewUser.Nick + "'s collection"
AnimeLists(animeLists, viewUser, user)
//- for status, animeList := range animeLists
//- h3= status
//- AnimeList(animeList, user)
component AnimeLists(animeLists map[string]*arn.AnimeList, viewUser *arn.User, user *arn.User)
if len(animeLists[arn.AnimeListStatusWatching].Items) == 0 && len(animeLists[arn.AnimeListStatusCompleted].Items) == 0 && len(animeLists[arn.AnimeListStatusPlanned].Items) == 0 && len(animeLists[arn.AnimeListStatusHold].Items) == 0 && len(animeLists[arn.AnimeListStatusDropped].Items) == 0 if len(animeLists[arn.AnimeListStatusWatching].Items) == 0 && len(animeLists[arn.AnimeListStatusCompleted].Items) == 0 && len(animeLists[arn.AnimeListStatusPlanned].Items) == 0 && len(animeLists[arn.AnimeListStatusHold].Items) == 0 && len(animeLists[arn.AnimeListStatusDropped].Items) == 0
p.no-data.mountable= viewUser.Nick + " hasn't added any anime yet." p.no-data.mountable= viewUser.Nick + " hasn't added any anime yet."
else else
@ -30,10 +37,6 @@ component AnimeLists(animeLists map[string]*arn.AnimeList, viewUser *arn.User, u
.anime-list-container .anime-list-container
h3.status-name Dropped h3.status-name Dropped
AnimeList(animeLists[arn.AnimeListStatusDropped], viewUser, user) AnimeList(animeLists[arn.AnimeListStatusDropped], viewUser, user)
//- for status, animeList := range animeLists
//- h3= status
//- AnimeList(animeList, user)
component AnimeList(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User) component AnimeList(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User)
table.anime-list table.anime-list

View File

@ -2,7 +2,7 @@
vertical vertical
width 100% width 100%
max-width table-width-normal max-width table-width-normal
margin 0 auto // margin 0 auto
margin-bottom 1rem margin-bottom 1rem
.anime-list .anime-list

View File

@ -19,7 +19,7 @@ func FilterByStatus(status string) aero.Handle {
return response return response
} }
return ctx.HTML(components.AnimeListFilteredByStatus(list, list.User(), user, status, ctx.URI())) return ctx.HTML(components.ProfileAnimeListFilteredByStatus(list, list.User(), user, status, ctx.URI()))
} }
} }

View File

@ -1,9 +1,12 @@
component AnimeListFilteredByStatus(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User, status string, uri string) component ProfileAnimeListFilteredByStatus(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User, status string, uri string)
ProfileHeader(viewUser, user, uri) ProfileHeader(viewUser, user, uri)
AnimeListFilteredByStatus(animeList, viewUser, user, status)
component AnimeListFilteredByStatus(animeList *arn.AnimeList, viewUser *arn.User, user *arn.User, status string)
if len(animeList.Items) == 0 if len(animeList.Items) == 0
p.no-data.mountable= viewUser.Nick + " hasn't added any anime to this list yet." p.no-data.mountable= viewUser.Nick + " hasn't added any anime to this list yet."
else else
.anime-list-container.fill-screen .anime-list-container.fill-screen
h3.status-name= arn.ListItemStatusName(status) //- h3.status-name= arn.ListItemStatusName(status)
AnimeList(animeList, viewUser, user) AnimeList(animeList, viewUser, user)

View File

@ -0,0 +1,10 @@
package artworks
import (
"github.com/aerogo/aero"
)
// Get artworks.
func Get(ctx *aero.Context) string {
return ctx.HTML("Coming soon™.")
}

View File

@ -7,7 +7,6 @@ import (
"github.com/aerogo/flow" "github.com/aerogo/flow"
"github.com/animenotifier/arn" "github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/components" "github.com/animenotifier/notify.moe/components"
"github.com/animenotifier/notify.moe/pages/frontpage"
"github.com/animenotifier/notify.moe/utils" "github.com/animenotifier/notify.moe/utils"
) )
@ -16,19 +15,8 @@ const maxFollowing = 5
const maxSoundTracks = 5 const maxSoundTracks = 5
const maxScheduleItems = 5 const maxScheduleItems = 5
// Get the dashboard or the frontpage when logged out. // Get the dashboard.
func Get(ctx *aero.Context) string { func Get(ctx *aero.Context) string {
user := utils.GetUser(ctx)
if user == nil {
return frontpage.Get(ctx)
}
return dashboard(ctx)
}
// Render the dashboard.
func dashboard(ctx *aero.Context) string {
var forumActivity []arn.Postable var forumActivity []arn.Postable
var followingList []*arn.User var followingList []*arn.User
var soundTracks []*arn.SoundTrack var soundTracks []*arn.SoundTrack

31
pages/home/home.go Normal file
View File

@ -0,0 +1,31 @@
package home
import (
"net/http"
"github.com/aerogo/aero"
"github.com/animenotifier/notify.moe/components"
"github.com/animenotifier/notify.moe/pages/frontpage"
"github.com/animenotifier/notify.moe/utils"
)
// Get the dashboard or the frontpage when logged out.
func Get(ctx *aero.Context) string {
user := utils.GetUser(ctx)
if user == nil {
return frontpage.Get(ctx)
}
viewUser := user
animeList := viewUser.AnimeList()
if animeList == nil {
return ctx.Error(http.StatusNotFound, "Anime list not found", nil)
}
animeList.PrefetchAnime()
animeList.Sort()
return ctx.HTML(components.AnimeLists(animeList.SplitByStatus(), animeList.User(), user))
}

View File

@ -59,60 +59,38 @@ component ProfileHeader(viewUser *arn.User, user *arn.User, uri string)
ProfileNavigation(viewUser, uri) ProfileNavigation(viewUser, uri)
component ProfileNavigation(viewUser *arn.User, uri string) component ProfileNavigation(viewUser *arn.User, uri string)
.buttons.tabs .tabs
a.button.tab.action(href="/+" + viewUser.Nick, data-action="diff", data-trigger="click") a.tab.action(href="/+" + viewUser.Nick, data-action="diff", data-trigger="click")
Icon("th") Icon("th")
span.tab-text Anime span.tab-text Anime
a.button.tab.action(href="/+" + viewUser.Nick + "/animelist/watching", data-action="diff", data-trigger="click") a.tab.action(href="/+" + viewUser.Nick + "/animelist/watching", data-action="diff", data-trigger="click")
Icon("list") Icon("list")
span.tab-text Collection span.tab-text Collection
a.button.tab.action(href="/+" + viewUser.Nick + "/threads", data-action="diff", data-trigger="click") a.tab.action(href="/+" + viewUser.Nick + "/threads", data-action="diff", data-trigger="click")
Icon("comment") Icon("comment")
span.tab-text Threads span.tab-text Threads
a.button.tab.action(href="/+" + viewUser.Nick + "/posts", data-action="diff", data-trigger="click") a.tab.action(href="/+" + viewUser.Nick + "/posts", data-action="diff", data-trigger="click")
Icon("comments") Icon("comments")
span.tab-text Posts span.tab-text Posts
a.button.tab.action(href="/+" + viewUser.Nick + "/soundtracks", data-action="diff", data-trigger="click") a.tab.action(href="/+" + viewUser.Nick + "/soundtracks", data-action="diff", data-trigger="click")
Icon("music") Icon("music")
span.tab-text Tracks span.tab-text Tracks
a.button.tab.action(href="/+" + viewUser.Nick + "/stats", data-action="diff", data-trigger="click") a.tab.action(href="/+" + viewUser.Nick + "/stats", data-action="diff", data-trigger="click")
Icon("area-chart") Icon("area-chart")
span.tab-text Stats span.tab-text Stats
a.button.tab.action(href="/+" + viewUser.Nick + "/followers", data-action="diff", data-trigger="click") a.tab.action(href="/+" + viewUser.Nick + "/followers", data-action="diff", data-trigger="click")
Icon("users") Icon("users")
span.tab-text Followers span.tab-text Followers
if strings.Contains(uri, "/animelist") if strings.Contains(uri, "/animelist")
hr hr
StatusTabs("/+" + viewUser.Nick + "/animelist") StatusTabs("/+" + viewUser.Nick + "/animelist")
component StatusTabs(urlPrefix string)
.buttons.tabs.status-tabs
a.button.tab.status-tab.action(href=urlPrefix + "/watching", data-action="diff", data-trigger="click")
Icon("play")
span.tab-text Watching
a.button.tab.status-tab.action(href=urlPrefix + "/completed", data-action="diff", data-trigger="click")
Icon("check")
span.tab-text Completed
a.button.tab.status-tab.action(href=urlPrefix + "/planned", data-action="diff", data-trigger="click")
Icon("forward")
span.tab-text Planned
a.button.tab.status-tab.action(href=urlPrefix + "/hold", data-action="diff", data-trigger="click")
Icon("pause")
span.tab-text On Hold
a.button.tab.status-tab.action(href=urlPrefix + "/dropped", data-action="diff", data-trigger="click")
Icon("stop")
span.tab-text Dropped
component Profile(viewUser *arn.User, user *arn.User, animeList *arn.AnimeList, threads []*arn.Thread, posts []*arn.Post, tracks []*arn.SoundTrack, uri string) component Profile(viewUser *arn.User, user *arn.User, animeList *arn.AnimeList, threads []*arn.Thread, posts []*arn.Post, tracks []*arn.SoundTrack, uri string)
ProfileHeader(viewUser, user, uri) ProfileHeader(viewUser, user, uri)

View File

@ -14,12 +14,12 @@ component Statistics(pieCharts ...*arn.PieChart)
p Data is collected for statistical purposes only. We respect user privacy and we will never display or sell critical data to 3rd party services. p Data is collected for statistical purposes only. We respect user privacy and we will never display or sell critical data to 3rd party services.
component StatisticsHeader component StatisticsHeader
.buttons.tabs .tabs
a.button.tab.action(href="/statistics", data-action="diff", data-trigger="click") a.tab.action(href="/statistics", data-action="diff", data-trigger="click")
Icon("user") Icon("user")
span.tab-text Users span.tab-text Users
a.button.tab.action(href="/statistics/anime", data-action="diff", data-trigger="click") a.tab.action(href="/statistics/anime", data-action="diff", data-trigger="click")
Icon("tv") Icon("tv")
span.tab-text Anime span.tab-text Anime

View File

@ -1,20 +1,20 @@
component Users(users []*arn.User) component Users(users []*arn.User)
h1.page-title Users h1.page-title Users
.buttons.tabs .tabs
a.button.tab.action(href="/users", data-action="diff", data-trigger="click") a.tab.action(href="/users", data-action="diff", data-trigger="click")
Icon("users") Icon("users")
span.tab-text Active span.tab-text Active
a.button.tab.action(href="/users/anime/watching", data-action="diff", data-trigger="click") a.tab.action(href="/users/anime/watching", data-action="diff", data-trigger="click")
Icon("tv") Icon("tv")
span.tab-text Watching span.tab-text Watching
a.button.tab.action(href="/users/osu", data-action="diff", data-trigger="click") a.tab.action(href="/users/osu", data-action="diff", data-trigger="click")
Icon("gamepad") Icon("gamepad")
span.tab-text Osu span.tab-text Osu
a.button.tab.action(href="/users/staff", data-action="diff", data-trigger="click") a.tab.action(href="/users/staff", data-action="diff", data-trigger="click")
Icon("user-secret") Icon("user-secret")
span.tab-text Staff span.tab-text Staff

View File

@ -24,7 +24,7 @@ export class AnimeNotifier {
imageFound: MutationQueue imageFound: MutationQueue
imageNotFound: MutationQueue imageNotFound: MutationQueue
unmount: MutationQueue // unmount: MutationQueue
constructor(app: Application) { constructor(app: Application) {
this.app = app this.app = app
@ -33,7 +33,7 @@ export class AnimeNotifier {
this.imageFound = new MutationQueue(elem => elem.classList.add("image-found")) this.imageFound = new MutationQueue(elem => elem.classList.add("image-found"))
this.imageNotFound = new MutationQueue(elem => elem.classList.add("image-not-found")) this.imageNotFound = new MutationQueue(elem => elem.classList.add("image-not-found"))
this.unmount = new MutationQueue(elem => elem.classList.remove("mounted")) // this.unmount = new MutationQueue(elem => elem.classList.remove("mounted"))
// These classes will never be removed on DOM diffs // These classes will never be removed on DOM diffs
Diff.persistentClasses.add("mounted") Diff.persistentClasses.add("mounted")
@ -140,7 +140,7 @@ export class AnimeNotifier {
this.visibilityObserver.disconnect() this.visibilityObserver.disconnect()
this.contentLoadedActions = Promise.all([ this.contentLoadedActions = Promise.all([
Promise.resolve().then(() => this.mountMountables()), // Promise.resolve().then(() => this.mountMountables()),
Promise.resolve().then(() => this.lazyLoadImages()), Promise.resolve().then(() => this.lazyLoadImages()),
Promise.resolve().then(() => this.displayLocalDates()), Promise.resolve().then(() => this.displayLocalDates()),
Promise.resolve().then(() => this.setSelectBoxValue()), Promise.resolve().then(() => this.setSelectBoxValue()),
@ -471,87 +471,87 @@ export class AnimeNotifier {
this.visibilityObserver.observe(img) this.visibilityObserver.observe(img)
} }
mountMountables() { // mountMountables() {
this.modifyDelayed("mountable", element => element.classList.add("mounted")) // this.modifyDelayed("mountable", element => element.classList.add("mounted"))
} // }
unmountMountables() { // unmountMountables() {
for(let element of findAll("mountable")) { // for(let element of findAll("mountable")) {
if(element.classList.contains("never-unmount")) { // if(element.classList.contains("never-unmount")) {
continue // continue
} // }
this.unmount.queue(element) // this.unmount.queue(element)
} // }
} // }
modifyDelayed(className: string, func: (element: HTMLElement) => void) { // modifyDelayed(className: string, func: (element: HTMLElement) => void) {
const maxDelay = 1000 // const maxDelay = 1000
const delay = 20 // const delay = 20
let time = 0 // let time = 0
let start = Date.now() // let start = Date.now()
let maxTime = start + maxDelay // let maxTime = start + maxDelay
let mountableTypes = new Map<string, number>() // let mountableTypes = new Map<string, number>()
let mountableTypeMutations = new Map<string, Array<any>>() // let mountableTypeMutations = new Map<string, Array<any>>()
let collection = document.getElementsByClassName(className) // let collection = document.getElementsByClassName(className)
if(collection.length === 0) { // if(collection.length === 0) {
return // return
} // }
// let delay = Math.min(maxDelay / collection.length, 20) // // let delay = Math.min(maxDelay / collection.length, 20)
for(let i = 0; i < collection.length; i++) { // for(let i = 0; i < collection.length; i++) {
let element = collection.item(i) as HTMLElement // let element = collection.item(i) as HTMLElement
let type = element.dataset.mountableType || "general" // let type = element.dataset.mountableType || "general"
if(mountableTypes.has(type)) { // if(mountableTypes.has(type)) {
time = mountableTypes.get(type) + delay // time = mountableTypes.get(type) + delay
mountableTypes.set(type, time) // mountableTypes.set(type, time)
} else { // } else {
time = start // time = start
mountableTypes.set(type, time) // mountableTypes.set(type, time)
mountableTypeMutations.set(type, []) // mountableTypeMutations.set(type, [])
} // }
if(time > maxTime) { // if(time > maxTime) {
time = maxTime // time = maxTime
} // }
mountableTypeMutations.get(type).push({ // mountableTypeMutations.get(type).push({
element, // element,
time // time
}) // })
} // }
for(let mountableType of mountableTypeMutations.keys()) { // for(let mountableType of mountableTypeMutations.keys()) {
let mutations = mountableTypeMutations.get(mountableType) // let mutations = mountableTypeMutations.get(mountableType)
let mutationIndex = 0 // let mutationIndex = 0
let updateBatch = () => { // let updateBatch = () => {
let now = Date.now() // let now = Date.now()
for(; mutationIndex < mutations.length; mutationIndex++) { // for(; mutationIndex < mutations.length; mutationIndex++) {
let mutation = mutations[mutationIndex] // let mutation = mutations[mutationIndex]
if(mutation.time > now) { // if(mutation.time > now) {
break // break
} // }
func(mutation.element) // func(mutation.element)
} // }
if(mutationIndex < mutations.length) { // if(mutationIndex < mutations.length) {
window.requestAnimationFrame(updateBatch) // window.requestAnimationFrame(updateBatch)
} // }
} // }
window.requestAnimationFrame(updateBatch) // window.requestAnimationFrame(updateBatch)
} // }
} // }
diff(url: string) { diff(url: string) {
if(url === this.app.currentPath) { if(url === this.app.currentPath) {
@ -570,17 +570,15 @@ export class AnimeNotifier {
history.pushState(url, null, url) history.pushState(url, null, url)
this.app.currentPath = url this.app.currentPath = url
this.app.markActiveLinks() this.app.markActiveLinks()
this.unmountMountables() // this.unmountMountables()
this.loading(true) this.loading(true)
// Delay by transition-speed // Delay by transition-speed
return delay(300).then(() => { return request
return request .then(html => this.app.setContent(html, true))
.then(html => this.app.setContent(html, true)) .then(() => this.app.emit("DOMContentLoaded"))
.then(() => this.app.emit("DOMContentLoaded")) .then(() => this.loading(false))
.then(() => this.loading(false)) .catch(console.error)
.catch(console.error)
})
} }
post(url, body) { post(url, body) {

View File

@ -1,10 +1,7 @@
html html
height 100% height 100%
font-family "Ubuntu", "Trebuchet MS", sans-serif font-family "Ubuntu", "Trebuchet MS", sans-serif
font-size 100% font-size 105%
.osx
font-size 95%
body body
tab-size 4 tab-size 4
@ -12,7 +9,6 @@ body
height 100% height 100%
color text-color color text-color
background-color bg-color background-color bg-color
font-size 1.05rem
a a
color link-color color link-color

View File

@ -23,7 +23,8 @@ input-focus-border-color = rgb(248, 165, 130)
// Button // Button
button-hover-color = link-hover-color button-hover-color = link-hover-color
forum-tag-hover-color = rgb(46, 85, 160) forum-tag-hover-color = #225db5
// forum-tag-hover-color = rgb(46, 85, 160)
// Forum // Forum
forum-width = 830px forum-width = 830px
@ -42,7 +43,7 @@ nav-link-hover-slide-color = main-color
// nav-link-hover-color = rgb(80, 80, 80) // nav-link-hover-color = rgb(80, 80, 80)
// Tables // Tables
table-width-normal = 1200px table-width-normal = 900px
// Loading animation // Loading animation
loading-anim-color = nav-link-hover-slide-color loading-anim-color = nav-link-hover-slide-color
@ -65,6 +66,6 @@ nav-height = 3.11rem
typography-margin = 0.4rem typography-margin = 0.4rem
// Timings // Timings
fade-speed = 200ms fade-speed = 1ms
transition-speed = 250ms transition-speed = 200ms
mountable-transition-speed = 300ms // mountable-transition-speed = 300ms

View File

@ -7,4 +7,8 @@
overflow-x hidden overflow-x hidden
overflow-y scroll overflow-y scroll
position relative position relative
// will-change transform // will-change transform
#columns
horizontal
height 100%

View File

@ -1,8 +1,8 @@
.mountable // .mountable
opacity 0 // opacity 0
transform translateY(0.85rem) // transform translateY(0.85rem)
transition opacity mountable-transition-speed ease, transform mountable-transition-speed ease // transition opacity mountable-transition-speed ease, transform mountable-transition-speed ease
.mounted // .mounted
opacity 1 !important // opacity 1 !important
transform translateY(0) // transform translateY(0)

View File

@ -68,9 +68,9 @@
.navigation-button, #search .navigation-button, #search
font-size 1.3em font-size 1.3em
> 550px // > 550px
#navigation // #navigation
padding 0 content-padding // padding 0 content-padding
> 930px > 930px
.navigation-button, #search .navigation-button, #search

View File

@ -1,11 +1,12 @@
sidebar-spacing-y = 0.75rem sidebar-spacing-y = 0.7rem
#sidebar #sidebar
vertical vertical
position fixed position fixed
left 0 left 0
top 0 top 0
min-width 265px z-index 10
min-width 200px
height 100% height 100%
background ui-background background ui-background
transform translateX(-100%) transform translateX(-100%)
@ -22,23 +23,34 @@ sidebar-spacing-y = 0.75rem
justify-content center justify-content center
margin 0.8rem 0 margin 0.8rem 0
> 700px
#sidebar
opacity 1
transform none
position static
pointer-events all
box-shadow none
border-right ui-border
.sidebar-visible .sidebar-visible
transform translateX(0) !important transform translateX(0) !important
pointer-events all !important pointer-events all !important
opacity 1 !important opacity 1 !important
.sidebar-link .sidebar-link
// color text-color color text-color
&.active &.active
.sidebar-button .sidebar-button
background rgb(245, 245, 245) background forum-tag-hover-color
color white
.sidebar-button .sidebar-button
horizontal horizontal
align-items center align-items center
padding sidebar-spacing-y content-padding padding sidebar-spacing-y 1rem
font-size 0.92rem
// background ui-background // background ui-background
.icon .icon
font-size 1.3rem font-size 1rem
margin-right content-padding margin-right 0.75rem

View File

@ -1,7 +1,7 @@
table table
width 100% width 100%
max-width table-width-normal max-width table-width-normal
margin 0 auto // margin 0 auto
tr tr
border-bottom-width 1px border-bottom-width 1px

View File

@ -1,10 +1,13 @@
.tab .tab
color text-color !important color text-color !important
padding 0.5rem 1rem
border-right ui-border
background-color rgb(224, 224, 224) !important
:hover, :hover,
&.active &.active
color white !important background-color bg-color !important
background-color forum-tag-hover-color !important transform none
// color text-color !important // color text-color !important
// :hover // :hover
@ -22,6 +25,11 @@
display none display none
.tabs .tabs
horizontal
margin-left calc(content-padding * -1)
margin-top calc(content-padding * -1)
margin-right calc(content-padding * -2)
border-bottom ui-border
// justify-content flex-start !important // justify-content flex-start !important
margin-bottom 1rem // margin-bottom 1rem
margin-top -0.6rem // margin-top -0.6rem

View File

@ -1,14 +0,0 @@
package utils
import (
"github.com/animenotifier/arn"
)
// ItemCSSClass removes mountable class if the list has too many items.
func ItemCSSClass(list *arn.AnimeList, index int) string {
if index > 20 || len(list.Items) > 50 {
return "anime-list-item"
}
return "anime-list-item mountable"
}