CSS and SW cleanup

This commit is contained in:
Eduard Urbach 2017-10-20 02:43:02 +02:00
parent 4fa15aad58
commit d50ba892e6
8 changed files with 148 additions and 115 deletions

View File

@ -38,7 +38,7 @@
:hover :hover
.plus-episode .plus-episode
opacity 1 opacity 1
pointer-events all pointer-events auto
.anime-list-item-episodes-watched .anime-list-item-episodes-watched
flex 0.4 flex 0.4

View File

@ -1,6 +1,3 @@
import * as actions from "./Actions"
import { displayAiringDate, displayDate } from "./DateView"
import { findAll, delay, canUseWebP, swapElements } from "./Utils"
import { Application } from "./Application" import { Application } from "./Application"
import { Diff } from "./Diff" import { Diff } from "./Diff"
import { MutationQueue } from "./MutationQueue" import { MutationQueue } from "./MutationQueue"
@ -10,6 +7,10 @@ import { TouchController } from "./TouchController"
import { Analytics } from "./Analytics" import { Analytics } from "./Analytics"
import { SideBar } from "./SideBar" import { SideBar } from "./SideBar"
import { InfiniteScroller } from "./InfiniteScroller" import { InfiniteScroller } from "./InfiniteScroller"
import { ServiceWorkerManager } from "./ServiceWorkerManager"
import { displayAiringDate, displayDate } from "./DateView"
import { findAll, delay, canUseWebP, swapElements } from "./Utils"
import * as actions from "./Actions"
export class AnimeNotifier { export class AnimeNotifier {
app: Application app: Application
@ -21,6 +22,7 @@ export class AnimeNotifier {
statusMessage: StatusMessage statusMessage: StatusMessage
visibilityObserver: IntersectionObserver visibilityObserver: IntersectionObserver
pushManager: PushManager pushManager: PushManager
serviceWorkerManager: ServiceWorkerManager
touchController: TouchController touchController: TouchController
sideBar: SideBar sideBar: SideBar
infiniteScroller: InfiniteScroller infiniteScroller: InfiniteScroller
@ -122,6 +124,9 @@ export class AnimeNotifier {
// Push manager // Push manager
this.pushManager = new PushManager() this.pushManager = new PushManager()
// Service worker
this.serviceWorkerManager = new ServiceWorkerManager(this, "/service-worker")
// Analytics // Analytics
this.analytics = new Analytics() this.analytics = new Analytics()
@ -164,7 +169,7 @@ export class AnimeNotifier {
onIdle() { onIdle() {
// Service worker // Service worker
this.registerServiceWorker() this.serviceWorkerManager.register()
// Analytics // Analytics
if(this.user) { if(this.user) {
@ -177,87 +182,6 @@ export class AnimeNotifier {
} }
} }
registerServiceWorker() {
if(!("serviceWorker" in navigator)) {
return
}
console.log("register service worker")
navigator.serviceWorker.register("/service-worker").then(registration => {
// registration.update()
})
navigator.serviceWorker.addEventListener("message", evt => {
this.onServiceWorkerMessage(evt)
})
// This will send a message to the service worker that the DOM has been loaded
let sendContentLoadedEvent = () => {
if(!navigator.serviceWorker.controller) {
return
}
// A reloadContent call should never trigger another reload
if(this.app.currentPath === this.lastReloadContentPath) {
console.log("reload finished.")
this.lastReloadContentPath = ""
return
}
let message = {
type: "loaded",
url: ""
}
// If mainPageLoaded is set, it means every single request is now an AJAX request for the /_/ prefixed page
if(this.mainPageLoaded) {
message.url = window.location.origin + "/_" + window.location.pathname
} else {
this.mainPageLoaded = true
message.url = window.location.href
}
console.log("checking for updates:", message.url)
navigator.serviceWorker.controller.postMessage(JSON.stringify(message))
}
// For future loaded events
document.addEventListener("DOMContentLoaded", sendContentLoadedEvent)
// If the page is loaded already, send the loaded event right now.
if(document.readyState !== "loading") {
sendContentLoadedEvent()
}
}
onServiceWorkerMessage(evt: ServiceWorkerMessageEvent) {
let message = JSON.parse(evt.data)
switch(message.type) {
case "new content":
if(message.url.includes("/_/")) {
// Content reload
this.contentLoadedActions.then(() => {
this.reloadContent(true)
})
} else {
// Full page reload
this.contentLoadedActions.then(() => {
this.reloadPage()
})
}
break
case "reload page":
console.log("service worker instructed to reload page...disobeying in test mode")
// location.reload(true)
break
}
}
dragAndDrop() { dragAndDrop() {
for(let element of findAll("inventory-slot")) { for(let element of findAll("inventory-slot")) {
// Skip elements that have their event listeners attached already // Skip elements that have their event listeners attached already

View File

@ -0,0 +1,96 @@
import { AnimeNotifier } from "./AnimeNotifier"
export class ServiceWorkerManager {
arn: AnimeNotifier
uri: string
constructor(arn: AnimeNotifier, uri: string) {
this.arn = arn
this.uri = uri
}
register() {
if(!("serviceWorker" in navigator)) {
return
}
console.log("register service worker")
navigator.serviceWorker.register(this.uri).then(registration => {
// registration.update()
})
navigator.serviceWorker.addEventListener("message", evt => {
this.onMessage(evt)
})
// This will send a message to the service worker that the DOM has been loaded
let sendContentLoadedEvent = () => {
if(!navigator.serviceWorker.controller) {
return
}
// A reloadContent call should never trigger another reload
if(this.arn.app.currentPath === this.arn.lastReloadContentPath) {
console.log("reload finished.")
this.arn.lastReloadContentPath = ""
return
}
let message = {
type: "loaded",
url: ""
}
// If mainPageLoaded is set, it means every single request is now an AJAX request for the /_/ prefixed page
if(this.arn.mainPageLoaded) {
message.url = window.location.origin + "/_" + window.location.pathname
} else {
this.arn.mainPageLoaded = true
message.url = window.location.href
}
console.log("checking for updates:", message.url)
this.postMessage(message)
}
// For future loaded events
document.addEventListener("DOMContentLoaded", sendContentLoadedEvent)
// If the page is loaded already, send the loaded event right now.
if(document.readyState !== "loading") {
sendContentLoadedEvent()
}
}
postMessage(message: any) {
navigator.serviceWorker.controller.postMessage(JSON.stringify(message))
}
onMessage(evt: ServiceWorkerMessageEvent) {
let message = JSON.parse(evt.data)
switch(message.type) {
case "new content":
if(message.url.includes("/_/")) {
// Content reload
this.arn.contentLoadedActions.then(() => {
this.arn.reloadContent(true)
})
} else {
// Full page reload
this.arn.contentLoadedActions.then(() => {
this.arn.reloadPage()
})
}
break
case "reload page":
console.log("service worker instructed to reload page...disobeying in test mode")
// location.reload(true)
break
}
}
}

View File

@ -11,7 +11,7 @@ pro-color = hsla(0, 100%, 73%, 0.87)
ui-border-color = rgba(0, 0, 0, 0.1) ui-border-color = rgba(0, 0, 0, 0.1)
ui-border = 1px solid ui-border-color ui-border = 1px solid ui-border-color
ui-hover-border-color = rgba(0, 0, 0, 0.15) ui-hover-border-color = rgba(0, 0, 0, 0.15)
ui-hover-border-color = 1px solid ui-hover-border-color ui-hover-border = 1px solid ui-hover-border-color
ui-background = rgb(254, 254, 254) ui-background = rgb(254, 254, 254)
// ui-hover-background = rgb(254, 254, 254) // ui-hover-background = rgb(254, 254, 254)
// ui-background = linear-gradient(to bottom, rgba(0, 0, 0, 0.02) 0%, rgba(0, 0, 0, 0.037) 100%) // ui-background = linear-gradient(to bottom, rgba(0, 0, 0, 0.02) 0%, rgba(0, 0, 0, 0.037) 100%)

View File

@ -16,7 +16,7 @@ sidebar-spacing-y = 0.7rem
pointer-events none pointer-events none
box-shadow shadow-medium box-shadow shadow-medium
transition opacity transition-speed ease, transform transition-speed ease transition opacity transition-speed ease, transform transition-speed ease
will-change opacity transition will-change opacity, transition
.user-image-container .user-image-container
horizontal horizontal
@ -29,14 +29,14 @@ sidebar-spacing-y = 0.7rem
opacity 1 opacity 1
transform none transform none
position static position static
pointer-events all pointer-events auto
box-shadow none box-shadow none
border-right ui-border border-right ui-border
background rgba(0, 0, 0, 0.03) background rgba(0, 0, 0, 0.03)
.sidebar-visible .sidebar-visible
transform translateX(0) !important transform translateX(0) !important
pointer-events all !important pointer-events auto !important
opacity 1 !important opacity 1 !important
.sidebar-link .sidebar-link

View File

@ -14,7 +14,7 @@
.status-message-action .status-message-action
color white !important color white !important
pointer-events all !important pointer-events auto !important
.error-message .error-message
color white color white

View File

@ -34,7 +34,7 @@
.widget-ui-element .widget-ui-element
vertical-wrap vertical-wrap
ui-element ui-element
transition border transition-speed ease, background transition-speed ease, transform transition-speed ease, transform color ease transition border transition-speed ease, background transition-speed ease, transform transition-speed ease, color transition-speed ease
margin-bottom 1rem margin-bottom 1rem
padding 0.5rem 1rem padding 0.5rem 1rem
width 100% width 100%

View File

@ -152,12 +152,65 @@ class MyServiceWorker {
onMessage(evt: any) { onMessage(evt: any) {
let message = JSON.parse(evt.data) let message = JSON.parse(evt.data)
let url = message.url switch(message.type) {
case "loaded":
this.onDOMContentLoaded(evt, message.url)
break
}
}
// onDOMContentLoaded is called when the client sent this service worker
// a message that the page has been loaded.
onDOMContentLoaded(evt: any, url: string) {
let refresh = RELOADS.get(url) let refresh = RELOADS.get(url)
let servedETag = ETAGS.get(url) let servedETag = ETAGS.get(url)
// If the user requests a sub-page we should prefetch the full page, too. // If the user requests a sub-page we should prefetch the full page, too.
if(url.includes("/_/")) { if(url.includes("/_/")) {
this.prefetchFullPage(url)
}
if(!refresh || !servedETag) {
return Promise.resolve()
}
return refresh.then((response: Response) => {
// When the actual network request was used by the client, response.bodyUsed is set.
// In that case the client is already up to date and we don"t need to tell the client to do a refresh.
if(response.bodyUsed) {
return
}
// Get the ETag of the cached response we sent to the client earlier.
let eTag = response.headers.get("ETag")
// Update ETag
ETAGS.set(url, eTag)
// Get CSP
let oldCSP = this.currentCSP
let csp = response.headers.get("Content-Security-Policy")
// If the CSP and therefore the sha-1 hash of the CSS changed, we need to do a reload.
if(csp != oldCSP) {
this.currentCSP = csp
if(oldCSP !== "") {
return this.forceClientReloadPage(url, evt.source)
}
}
// If the ETag changed, we need to do a reload.
if(eTag !== servedETag) {
return this.forceClientReloadContent(url, evt.source)
}
// Do nothing
return Promise.resolve()
})
}
prefetchFullPage(url: string) {
let fullPage = new Request(url.replace("/_/", "/")) let fullPage = new Request(url.replace("/_/", "/"))
let fullPageRefresh = fetch(fullPage, { let fullPageRefresh = fetch(fullPage, {
@ -176,46 +229,6 @@ class MyServiceWorker {
RELOADS.set(fullPage.url, fullPageRefresh) RELOADS.set(fullPage.url, fullPageRefresh)
} }
if(!refresh || !servedETag) {
return Promise.resolve()
}
return refresh.then((response: Response) => {
// If the fresh copy was used to serve the request instead of the cache,
// we don"t need to tell the client to do a refresh.
if(response.bodyUsed) {
return
}
// Get ETag
let eTag = response.headers.get("ETag")
// Update ETag
ETAGS.set(url, eTag)
// Get CSP
let oldCSP = this.currentCSP
let csp = response.headers.get("Content-Security-Policy")
if(csp != oldCSP) {
this.currentCSP = csp
if(oldCSP !== "") {
return this.forceClientReloadPage(url, evt.source)
}
}
// If the ETag changed, we need to do a reload.
// If the CSP and therefore the sha-1 hash of the CSS changed, we need to do a reload.
if(eTag !== servedETag) {
return this.forceClientReloadContent(url, evt.source)
}
// Do nothing
return Promise.resolve()
})
}
onPush(evt: PushEvent) { onPush(evt: PushEvent) {
var payload = evt.data ? evt.data.json() : {} var payload = evt.data ? evt.data.json() : {}
@ -320,7 +333,7 @@ class MyServiceWorker {
return cache.addAll([ return cache.addAll([
"./", "./",
"./scripts", "./scripts",
"https://fonts.gstatic.com/s/ubuntu/v10/2Q-AW1e_taO6pHwMXcXW5w.ttf" "https://fonts.gstatic.com/s/ubuntu/v11/4iCs6KVjbNBYlgoKfw7z.ttf"
]) ])
}) })
} }