Improve the loading screen error message

- Fix subtitle if the previously selected song had the same title
This commit is contained in:
LoveEevee 2020-03-16 12:54:21 +03:00
parent c5f85d0d87
commit 33b9b206a7
7 changed files with 147 additions and 43 deletions

View File

@ -117,3 +117,20 @@ body{
color: #777; color: #777;
text-shadow: 0.05em 0.05em #fff; text-shadow: 0.05em 0.05em #fff;
} }
.view-outer.loader-error-div,
.loader-error-div .diag-txt{
display: none
}
.loader-error-div{
font-family: sans-serif;
}
.loader-error-div .debug-link{
color: #00f;
text-decoration: underline;
cursor: pointer;
float: right;
}
.loader-error-div .diag-txt textarea,
.loader-error-div .diag-txt iframe{
height: 10em;
}

View File

@ -108,8 +108,8 @@ kbd{
.left-buttons .taibtn{ .left-buttons .taibtn{
margin-right: 0.4em; margin-right: 0.4em;
} }
#diag-txt textarea, .diag-txt textarea,
#diag-txt iframe{ .diag-txt iframe{
width: 100%; width: 100%;
height: 5em; height: 5em;
font-size: inherit; font-size: inherit;

View File

@ -5,7 +5,7 @@
cancelTouch = false cancelTouch = false
this.endButton = this.getElement("view-end-button") this.endButton = this.getElement("view-end-button")
this.diagTxt = document.getElementById("diag-txt") this.diagTxt = this.getElement("diag-txt")
this.version = document.getElementById("version-link").href this.version = document.getElementById("version-link").href
this.tutorialOuter = this.getElement("view-outer") this.tutorialOuter = this.getElement("view-outer")
if(touchEnabled){ if(touchEnabled){

View File

@ -5,6 +5,7 @@ class Loader{
this.assetsDiv = document.getElementById("assets") this.assetsDiv = document.getElementById("assets")
this.screen = document.getElementById("screen") this.screen = document.getElementById("screen")
this.startTime = Date.now() this.startTime = Date.now()
this.errorMessages = []
var promises = [] var promises = []
@ -28,17 +29,24 @@ class Loader{
if(gameConfig.custom_js){ if(gameConfig.custom_js){
var script = document.createElement("script") var script = document.createElement("script")
this.addPromise(pageEvents.load(script)) var url = gameConfig.custom_js + queryString
script.src = gameConfig.custom_js + queryString this.addPromise(pageEvents.load(script), url)
script.src = url
document.head.appendChild(script) document.head.appendChild(script)
} }
assets.js.forEach(name => { assets.js.forEach(name => {
var script = document.createElement("script") var script = document.createElement("script")
this.addPromise(pageEvents.load(script)) var url = "/src/js/" + name + queryString
script.src = "/src/js/" + name + queryString this.addPromise(pageEvents.load(script), url)
script.src = url
document.head.appendChild(script) document.head.appendChild(script)
}) })
var pageVersion = versionLink.href
var index = pageVersion.lastIndexOf("/")
if(index !== -1){
pageVersion = pageVersion.slice(index + 1)
}
this.addPromise(new Promise((resolve, reject) => { this.addPromise(new Promise((resolve, reject) => {
if( if(
versionLink.href !== gameConfig._version.url && versionLink.href !== gameConfig._version.url &&
@ -69,39 +77,43 @@ class Loader{
} }
var interval = setInterval(checkStyles, 100) var interval = setInterval(checkStyles, 100)
checkStyles() checkStyles()
})) }), "Version on the page and config does not match\n(page: " + pageVersion + ",\nconfig: "+ gameConfig._version.commit + ")")
for(var name in assets.fonts){ for(var name in assets.fonts){
this.addPromise(new FontFace(name, "url('" + gameConfig.assets_baseurl + "fonts/" + assets.fonts[name] + "')").load().then(font => { var url = gameConfig.assets_baseurl + "fonts/" + assets.fonts[name]
this.addPromise(new FontFace(name, "url('" + url + "')").load().then(font => {
document.fonts.add(font) document.fonts.add(font)
})) }), url)
} }
assets.img.forEach(name => { assets.img.forEach(name => {
var id = this.getFilename(name) var id = this.getFilename(name)
var image = document.createElement("img") var image = document.createElement("img")
this.addPromise(pageEvents.load(image)) var url = gameConfig.assets_baseurl + "img/" + name
this.addPromise(pageEvents.load(image), url)
image.id = name image.id = name
image.src = gameConfig.assets_baseurl + "img/" + name image.src = url
this.assetsDiv.appendChild(image) this.assetsDiv.appendChild(image)
assets.image[id] = image assets.image[id] = image
}) })
assets.views.forEach(name => { assets.views.forEach(name => {
var id = this.getFilename(name) var id = this.getFilename(name)
this.addPromise(this.ajax("/src/views/" + name + queryString).then(page => { var url = "/src/views/" + name + queryString
this.addPromise(this.ajax(url).then(page => {
assets.pages[id] = page assets.pages[id] = page
})) }), url)
}) })
this.addPromise(this.ajax("/api/songs").then(songs => { this.addPromise(this.ajax("/api/songs").then(songs => {
assets.songsDefault = JSON.parse(songs) assets.songsDefault = JSON.parse(songs)
assets.songs = assets.songsDefault assets.songs = assets.songsDefault
})) }), "/api/songs")
this.addPromise(this.ajax(gameConfig.assets_baseurl + "img/vectors.json" + queryString).then(response => { var url = gameConfig.assets_baseurl + "img/vectors.json" + queryString
this.addPromise(this.ajax(url).then(response => {
vectors = JSON.parse(response) vectors = JSON.parse(response)
})) }), url)
this.afterJSCount = this.afterJSCount =
["blurPerformance"].length + ["blurPerformance"].length +
@ -112,6 +124,9 @@ class Loader{
(gameConfig.accounts ? 1 : 0) (gameConfig.accounts ? 1 : 0)
Promise.all(this.promises).then(() => { Promise.all(this.promises).then(() => {
if(this.error){
return
}
snd.buffer = new SoundBuffer() snd.buffer = new SoundBuffer()
snd.musicGain = snd.buffer.createGain() snd.musicGain = snd.buffer.createGain()
@ -131,20 +146,20 @@ class Loader{
this.afterJSCount = 0 this.afterJSCount = 0
assets.audioSfx.forEach(name => { assets.audioSfx.forEach(name => {
this.addPromise(this.loadSound(name, snd.sfxGain)) this.addPromise(this.loadSound(name, snd.sfxGain), this.soundUrl(name))
}) })
assets.audioMusic.forEach(name => { assets.audioMusic.forEach(name => {
this.addPromise(this.loadSound(name, snd.musicGain)) this.addPromise(this.loadSound(name, snd.musicGain), this.soundUrl(name))
}) })
assets.audioSfxLR.forEach(name => { assets.audioSfxLR.forEach(name => {
this.addPromise(this.loadSound(name, snd.sfxGain).then(sound => { this.addPromise(this.loadSound(name, snd.sfxGain).then(sound => {
var id = this.getFilename(name) var id = this.getFilename(name)
assets.sounds[id + "_p1"] = assets.sounds[id].copy(snd.sfxGainL) assets.sounds[id + "_p1"] = assets.sounds[id].copy(snd.sfxGainL)
assets.sounds[id + "_p2"] = assets.sounds[id].copy(snd.sfxGainR) assets.sounds[id + "_p2"] = assets.sounds[id].copy(snd.sfxGainR)
})) }), this.soundUrl(name))
}) })
assets.audioSfxLoud.forEach(name => { assets.audioSfxLoud.forEach(name => {
this.addPromise(this.loadSound(name, snd.sfxLoudGain)) this.addPromise(this.loadSound(name, snd.sfxLoudGain), this.soundUrl(name))
}) })
this.canvasTest = new CanvasTest() this.canvasTest = new CanvasTest()
@ -154,7 +169,7 @@ class Loader{
// Less than 50 fps with blur enabled // Less than 50 fps with blur enabled
disableBlur = true disableBlur = true
} }
})) }), "blurPerformance")
if(gameConfig.accounts){ if(gameConfig.accounts){
this.addPromise(this.ajax("/api/scores/get").then(response => { this.addPromise(this.ajax("/api/scores/get").then(response => {
@ -166,7 +181,7 @@ class Loader{
scoreStorage.load(response.scores) scoreStorage.load(response.scores)
pageEvents.send("login", account.username) pageEvents.send("login", account.username)
} }
})) }), "/api/scores/get")
} }
settings = new Settings() settings = new Settings()
@ -174,6 +189,9 @@ class Loader{
scoreStorage = new ScoreStorage() scoreStorage = new ScoreStorage()
Promise.all(this.promises).then(() => { Promise.all(this.promises).then(() => {
if(this.error){
return
}
if(!account.loggedIn){ if(!account.loggedIn){
scoreStorage.load() scoreStorage.load()
} }
@ -250,27 +268,36 @@ class Loader{
}) })
} }
addPromise(promise){ addPromise(promise, url){
this.promises.push(promise) this.promises.push(promise)
promise.then(this.assetLoaded.bind(this), this.errorMsg.bind(this)) promise.then(this.assetLoaded.bind(this), response => {
this.errorMsg(response, url)
return Promise.resolve()
})
}
soundUrl(name){
return gameConfig.assets_baseurl + "audio/" + name
} }
loadSound(name, gain){ loadSound(name, gain){
var id = this.getFilename(name) var id = this.getFilename(name)
return gain.load(gameConfig.assets_baseurl + "audio/" + name).then(sound => { return gain.load(this.soundUrl(name)).then(sound => {
assets.sounds[id] = sound assets.sounds[id] = sound
}) })
} }
getFilename(name){ getFilename(name){
return name.slice(0, name.lastIndexOf(".")) return name.slice(0, name.lastIndexOf("."))
} }
errorMsg(error){ errorMsg(error, url){
if(Array.isArray(error) && error[1] instanceof HTMLElement){ if(url || error){
error = error[0] + ": " + error[1].outerHTML if(url){
error = (Array.isArray(error) ? error[0] + ": " : (error ? error + ": " : "")) + url
}
this.errorMessages.push(error)
pageEvents.send("loader-error", url || error)
} }
console.error(error)
pageEvents.send("loader-error", error)
if(!this.error){ if(!this.error){
this.error = true this.error = true
cancelTouch = false
this.loaderDiv.classList.add("loaderError") this.loaderDiv.classList.add("loaderError")
if(typeof allStrings === "object"){ if(typeof allStrings === "object"){
var lang = localStorage.lang var lang = localStorage.lang
@ -288,15 +315,58 @@ class Loader{
if(!lang){ if(!lang){
lang = "en" lang = "en"
} }
var errorOccured = allStrings[lang].errorOccured loader.screen.getElementsByClassName("view-content")[0].innerText = allStrings[lang].errorOccured
}
var loaderError = loader.screen.getElementsByClassName("loader-error-div")[0]
loaderError.style.display = "flex"
var diagTxt = loader.screen.getElementsByClassName("diag-txt")[0]
var debugLink = loader.screen.getElementsByClassName("debug-link")[0]
if(navigator.userAgent.indexOf("Android") >= 0){
var iframe = document.createElement("iframe")
diagTxt.appendChild(iframe)
var body = iframe.contentWindow.document.body
body.setAttribute("style", `
font-family: monospace;
margin: 2px 0 0 2px;
white-space: pre-wrap;
word-break: break-all;
cursor: text;
`)
body.setAttribute("onblur", `
getSelection().removeAllRanges()
`)
this.errorTxt = {
element: body,
method: "innerText"
}
}else{ }else{
var errorOccured = "An error occurred, please refresh" var textarea = document.createElement("textarea")
textarea.readOnly = true
diagTxt.appendChild(textarea)
if(!this.touchEnabled){
textarea.addEventListener("focus", () => {
textarea.select()
})
textarea.addEventListener("blur", () => {
getSelection().removeAllRanges()
})
} }
this.loaderPercentage.appendChild(document.createElement("br")) this.errorTxt = {
this.loaderPercentage.appendChild(document.createTextNode(errorOccured)) element: textarea,
this.clean() method: "value"
} }
} }
var show = () => {
diagTxt.style.display = "block"
debugLink.style.display = "none"
}
debugLink.addEventListener("click", show)
debugLink.addEventListener("touchstart", show)
this.clean(true)
}
var percentage = Math.floor(this.loadedAssets * 100 / (this.promises.length + this.afterJSCount))
this.errorTxt.element[this.errorTxt.method] = "```\n" + this.errorMessages.join("\n") + "\nPercentage: " + percentage + "%\n```"
}
assetLoaded(){ assetLoaded(){
if(!this.error){ if(!this.error){
this.loadedAssets++ this.loadedAssets++
@ -314,7 +384,11 @@ class Loader{
var request = new XMLHttpRequest() var request = new XMLHttpRequest()
request.open("GET", url) request.open("GET", url)
pageEvents.load(request).then(() => { pageEvents.load(request).then(() => {
if(request.status === 200){
resolve(request.response) resolve(request.response)
}else{
reject()
}
}, reject) }, reject)
if(customRequest){ if(customRequest){
customRequest(request) customRequest(request)
@ -322,14 +396,18 @@ class Loader{
request.send() request.send()
}) })
} }
clean(){ clean(error){
var fontDetectDiv = document.getElementById("fontdetectHelper") var fontDetectDiv = document.getElementById("fontdetectHelper")
if(fontDetectDiv){ if(fontDetectDiv){
fontDetectDiv.parentNode.removeChild(fontDetectDiv) fontDetectDiv.parentNode.removeChild(fontDetectDiv)
} }
delete this.loaderDiv
delete this.loaderPercentage delete this.loaderPercentage
delete this.loaderProgress delete this.loaderProgress
if(!error){
delete this.promises delete this.promises
delete this.errorText
}
pageEvents.remove(root, "touchstart") pageEvents.remove(root, "touchstart")
} }
} }

View File

@ -246,6 +246,7 @@ class SongSelect{
this.selectedSong = 0 this.selectedSong = 0
this.selectedDiff = 0 this.selectedDiff = 0
this.lastCurrentSong = {}
assets.sounds["bgm_songsel"].playLoop(0.1, false, 0, 1.442, 3.506) assets.sounds["bgm_songsel"].playLoop(0.1, false, 0, 1.442, 3.506)
if(!assets.customSongs && !fromTutorial && !("selectedSong" in localStorage) && !songId){ if(!assets.customSongs && !fromTutorial && !("selectedSong" in localStorage) && !songId){
@ -1243,8 +1244,9 @@ class SongSelect{
highlight = 0 highlight = 0
} }
if(this.currentSongTitle !== currentSong.title){ if(this.lastCurrentSong.title !== currentSong.title || this.lastCurrentSong.subtitle !== currentSong.subtitle){
this.currentSongTitle = currentSong.title this.lastCurrentSong.title = currentSong.title
this.lastCurrentSong.subtitle = currentSong.subtitle
this.currentSongCache.clear() this.currentSongCache.clear()
} }

View File

@ -2,7 +2,7 @@
<div class="view"> <div class="view">
<div class="view-title stroke-sub"></div> <div class="view-title stroke-sub"></div>
<div class="view-content"></div> <div class="view-content"></div>
<div id="diag-txt"></div> <div class="diag-txt"></div>
<div class="left-buttons"> <div class="left-buttons">
<div id="link-issues" class="taibtn stroke-sub link-btn"> <div id="link-issues" class="taibtn stroke-sub link-btn">
<a target="_blank"></a> <a target="_blank"></a>

View File

@ -2,3 +2,10 @@
<div class="progress"></div> <div class="progress"></div>
<span class="percentage">0%</span> <span class="percentage">0%</span>
</div> </div>
<div class="view-outer loader-error-div">
<div class="view">
<div class="view-content">An error occurred, please refresh</div>
<div class="diag-txt"></div>
<span class="debug-link">Debug</span>
</div>
</div>