CSS and SW cleanup
This commit is contained in:
parent
4fa15aad58
commit
d50ba892e6
@ -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
|
||||||
|
@ -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
|
||||||
|
96
scripts/ServiceWorkerManager.ts
Normal file
96
scripts/ServiceWorkerManager.ts
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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%)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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%
|
||||||
|
@ -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"
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user