Skip to content

Commit

Permalink
feat: prevent endless reloading (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
pimlie authored and pi0 committed Sep 21, 2019
1 parent cb5f511 commit 260dd61
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
60 changes: 57 additions & 3 deletions app/app.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="loading-screen" :class="{ hide: allDone }">
<div class="loading-screen" :class="{ hide: allDone && !preventReload }">
<div class="row">
<transition appear>
<svg class="logo" width="220" height="166" xmlns="http://www.w3.org/2000/svg">
Expand All @@ -12,7 +12,7 @@
</svg>
</transition>
</div>
<div v-if="!bundles.length && !hasErrors" class="row placeholder">
<div v-if="!bundles.length && !hasErrors && !preventReload" class="row placeholder">
<transition appear>
<h3>Loading...</h3>
</transition>
Expand All @@ -22,6 +22,15 @@
An error occured, please look at Nuxt.js terminal.
</h3>
</div>
<div v-else-if="preventReload" class="reload_prevented">
<h3 class="hasErrors">Failed to show Nuxt.js app after {{ maxReloadCount }} reloads</h3>
<p>
Your Nuxt.js app could not be shown even though the webpack build appears to have finished.
</p>
<p>
Try to reload the page manually, if this problem persists try to restart your Nuxt.js dev server.
</p>
</div>
<transition-group v-else>
<div v-for="bundle of bundles" :key="bundle" class="row">
<h3>{{ bundle | capitalize }} bundle</h3>
Expand All @@ -43,6 +52,7 @@ import fetch from 'unfetch'
import capitalizeMixin from './mixins/capitalize'
import logMixin from './mixins/log'
import sseMixin from './mixins/sse'
import storageMixin from './mixins/storage'
const waitFor = ms => new Promise(resolve => setTimeout(resolve, ms))
Expand All @@ -52,22 +62,36 @@ export default {
mixins: [
capitalizeMixin,
logMixin,
sseMixin
sseMixin,
storageMixin
],
data() {
return {
allDone: false,
hasErrors: false,
isFinished: false,
maxReloadCount: 5,
preventReload: false,
manualReload: false,
baseURL: window.$BASE_URL,
bundles: [],
states: {}
}
},
beforeMount() {
if (!this.canReload()) {
this.preventReload = true
return
}
},
mounted() {
if (this.preventReload) {
return
}
this.onData(window.$STATE)
this.sseConnect(`${this.baseURL}_loading/sse`)
this.setTimeout()
Expand Down Expand Up @@ -152,6 +176,33 @@ export default {
this.hasErrors = data.hasErrors
},
canReload() {
this.reloadCount = parseInt(this.retrieveItem('reloadCount')) || 0
const lastReloadTime = parseInt(this.retrieveItem('lastReloadTime')) || 0
this.loadingTime = new Date().getTime()
const canReload = this.reloadCount < this.maxReloadCount
const reloadWasOutsideThreshold = lastReloadTime && this.loadingTime > 1000 + lastReloadTime
// remove items when the last reload was outside our 1s threshold
// or when we've hit the max reload count so eg when the user
// manually reloads we start again with 5 tries
if (!canReload || reloadWasOutsideThreshold) {
this.removeItem('reloadCount')
this.removeItem('lastReloadTime')
this.reloadCount = 0
return canReload
}
return true
},
updateReloadItems() {
this.storeItem('reloadCount', 1 + this.reloadCount)
this.storeItem('lastReloadTime', this.loadingTime)
},
async reload() {
if (this._reloading) {
return
Expand All @@ -170,6 +221,9 @@ export default {
// Wait for transition (and hopefully renderer to be ready)
await waitFor(500)
// Update reload counter
this.updateReloadItems()
// Reload the page
window.location.reload(true)
}
Expand Down
9 changes: 9 additions & 0 deletions app/css/loading.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ h4 {
color: #383838;
}

.reload_prevented {
width: 500px;
max-width: 85vw;
}

.reload_prevented p {
margin-bottom: 1rem;
}

.progress_bar_container {
background-color: #DDDDDD;
border-radius: 6px;
Expand Down
25 changes: 25 additions & 0 deletions app/mixins/storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const baseKey = '__nuxt_loading_screen_'

export default {
methods: {
createItemKey (key) {
return `${baseKey}${key}`
},

storeItem (key, value) {
try {
sessionStorage.setItem(this.createItemKey(key), `${value}`)
} catch (err) {
console.error(err)
}
},

retrieveItem (key) {
return sessionStorage.getItem(this.createItemKey(key))
},

removeItem (key) {
sessionStorage.removeItem(this.createItemKey(key))
}
}
}

0 comments on commit 260dd61

Please sign in to comment.