Lazy load images
This commit is contained in:
parent
79ba7ecf3b
commit
b6c4968c6c
@ -1,14 +1,14 @@
|
||||
component InputText(id string, value string, label string, placeholder string)
|
||||
.widget-input
|
||||
label(for=id)= label + ":"
|
||||
input.widget-element.action(id=id, type="text", value=value, placeholder=placeholder, data-action="save", data-trigger="change")
|
||||
input.widget-element.action(id=id, type="text", value=value, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change")
|
||||
|
||||
component InputTextArea(id string, value string, label string, placeholder string)
|
||||
.widget-input
|
||||
label(for=id)= label + ":"
|
||||
textarea.widget-element.action(id=id, placeholder=placeholder, data-action="save", data-trigger="change")= value
|
||||
textarea.widget-element.action(id=id, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change")= value
|
||||
|
||||
component InputNumber(id string, value int, label string, placeholder string, min string, max string)
|
||||
.widget-input
|
||||
label(for=id)= label + ":"
|
||||
input.widget-element.action(id=id, type="number", value=value, min=min, max=max, placeholder=placeholder, data-action="save", data-trigger="change")
|
||||
input.widget-element.action(id=id, type="number", value=value, min=min, max=max, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change")
|
@ -159,8 +159,10 @@ component Anime(anime *arn.Anime, user *arn.User)
|
||||
//- if providers.AnimePlanet
|
||||
//- a.light-button(href="http://www.anime-planet.com/anime/" + providers.AnimePlanet.providerId, target="_blank") AnimePlanet
|
||||
|
||||
.sources
|
||||
p Powered by Kitsu.
|
||||
.footer
|
||||
a(href="/api/anime/" + anime.ID) Anime API
|
||||
span |
|
||||
span Powered by Kitsu.
|
||||
//- if descriptionSource
|
||||
//- span= " Summary by " + summarySource + "."
|
||||
//- //-
|
||||
|
@ -87,10 +87,11 @@
|
||||
.anime-rating-categories
|
||||
vertical
|
||||
|
||||
.sources
|
||||
.footer
|
||||
font-size 0.8rem
|
||||
opacity 0.5
|
||||
opacity 0.7
|
||||
margin-top 0.5rem
|
||||
text-align center
|
||||
|
||||
.relations
|
||||
horizontal-wrap
|
||||
|
@ -84,6 +84,6 @@ component Profile(viewUser *arn.User, user *arn.User, animeList *arn.AnimeList,
|
||||
.spacer
|
||||
.post-likes= len(post.Likes)
|
||||
|
||||
if user != nil && user.Role == "admin"
|
||||
.side-note
|
||||
a(href="/api/user/" + viewUser.ID)= "API: ", viewUser.Nick
|
||||
|
||||
.footer
|
||||
a(href="/api/user/" + viewUser.ID) User API
|
@ -1,7 +1,7 @@
|
||||
component Settings(user *arn.User)
|
||||
h2.page-title Settings
|
||||
.widgets(data-api="/api/user/" + user.ID)
|
||||
.widget.mountable
|
||||
.widgets
|
||||
.widget.mountable(data-api="/api/user/" + user.ID)
|
||||
h3.widget-title
|
||||
Icon("user")
|
||||
span Personal
|
||||
@ -10,11 +10,19 @@ component Settings(user *arn.User)
|
||||
InputText("Tagline", user.Tagline, "Tagline", "Text that appears below your username")
|
||||
InputText("Website", user.Website, "Website", "Your homepage")
|
||||
|
||||
.widget.mountable
|
||||
.widget.mountable(data-api="/api/user/" + user.ID)
|
||||
h3.widget-title
|
||||
Icon("cubes")
|
||||
span Accounts
|
||||
|
||||
InputText("Accounts.AniList.Nick", user.Accounts.AniList.Nick, "AniList", "Your username on anilist.co")
|
||||
InputText("Accounts.MyAnimeList.Nick", user.Accounts.MyAnimeList.Nick, "MyAnimeList", "Your username on myanimelist.net")
|
||||
InputText("Accounts.Kitsu.Nick", user.Accounts.Kitsu.Nick, "Kitsu", "Your username on kitsu.io")
|
||||
InputText("Accounts.AnimePlanet.Nick", user.Accounts.Kitsu.Nick, "Kitsu", "Your username on kitsu.io")
|
||||
InputText("Accounts.AnimePlanet.Nick", user.Accounts.AnimePlanet.Nick, "AnimePlanet", "Your username on anime-planet.com")
|
||||
|
||||
.widget.mountable(data-api="/api/settings/" + user.ID)
|
||||
h3.widget-title
|
||||
Icon("cogs")
|
||||
span Settings
|
||||
|
||||
InputText("TitleLanguage", user.Settings().TitleLanguage, "Title language", "Language of anime titles")
|
@ -5,9 +5,21 @@ import * as actions from "./actions"
|
||||
|
||||
export class AnimeNotifier {
|
||||
app: Application
|
||||
visibilityObserver: IntersectionObserver
|
||||
|
||||
constructor(app: Application) {
|
||||
this.app = app
|
||||
this.visibilityObserver = new IntersectionObserver(
|
||||
entries => {
|
||||
for(let entry of entries) {
|
||||
if(entry.intersectionRatio > 0) {
|
||||
entry.target["became visible"]()
|
||||
this.visibilityObserver.unobserve(entry.target)
|
||||
}
|
||||
}
|
||||
},
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
onReadyStateChange() {
|
||||
@ -24,6 +36,15 @@ export class AnimeNotifier {
|
||||
this.app.run()
|
||||
}
|
||||
|
||||
onContentLoaded() {
|
||||
this.visibilityObserver.disconnect()
|
||||
|
||||
// Update each of these asynchronously
|
||||
Promise.resolve().then(() => this.updateMountables())
|
||||
Promise.resolve().then(() => this.updateActions())
|
||||
Promise.resolve().then(() => this.lazyLoadImages())
|
||||
}
|
||||
|
||||
reloadContent() {
|
||||
return fetch("/_" + this.app.currentPath, {
|
||||
credentials: "same-origin"
|
||||
@ -57,9 +78,24 @@ export class AnimeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
updateAvatars() {
|
||||
lazyLoadImages() {
|
||||
for(let element of findAll("user-image")) {
|
||||
let img = element as HTMLImageElement
|
||||
this.lazyLoadImage(element as HTMLImageElement)
|
||||
}
|
||||
|
||||
for(let element of findAll("anime-cover-image")) {
|
||||
this.lazyLoadImage(element as HTMLImageElement)
|
||||
}
|
||||
}
|
||||
|
||||
lazyLoadImage(img: HTMLImageElement) {
|
||||
// Prevent browser from loading it instantly
|
||||
img["original source"] = img.src
|
||||
img.src = ""
|
||||
|
||||
// Once the image becomes visible, load it
|
||||
img["became visible"] = () => {
|
||||
img.src = img["original source"]
|
||||
|
||||
if(img.naturalWidth === 0) {
|
||||
img.onload = function() {
|
||||
@ -73,6 +109,8 @@ export class AnimeNotifier {
|
||||
img.classList.add("user-image-found")
|
||||
}
|
||||
}
|
||||
|
||||
this.visibilityObserver.observe(img)
|
||||
}
|
||||
|
||||
updateMountables() {
|
||||
@ -94,13 +132,6 @@ export class AnimeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
onContentLoaded() {
|
||||
// Update each of these asynchronously
|
||||
Promise.resolve().then(() => this.updateMountables())
|
||||
Promise.resolve().then(() => this.updateAvatars())
|
||||
Promise.resolve().then(() => this.updateActions())
|
||||
}
|
||||
|
||||
onPopState(e: PopStateEvent) {
|
||||
if(e.state) {
|
||||
this.app.load(e.state, {
|
||||
|
Loading…
Reference in New Issue
Block a user