diff --git a/public/src/css/loader.css b/public/src/css/loader.css
index 2a34c07..6e7f960 100644
--- a/public/src/css/loader.css
+++ b/public/src/css/loader.css
@@ -28,4 +28,64 @@
font-family: sans-serif;
font-size: 5vmin;
color: white;
-}
\ No newline at end of file
+}
+
+#unsupportedBrowser{
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ max-height: 100%;
+ overflow: hidden auto;
+ padding: 10px;
+ background: #aef;
+ font-family: sans-serif;
+ font-size: 20px;
+ z-index: 10;
+}
+#unsupportedBrowser::before{
+ content: "!";
+ display: inline-block;
+ width: 30px;
+ height: 30px;
+ margin-right: 10px;
+ background: #39a;
+ color: #fff;
+ text-align: center;
+ line-height: 30px;
+}
+#unsupportedBrowser.hidden{
+ width: 30px;
+}
+#unsupportedBrowser.hidden *{
+ display: none !important;
+}
+#unsupportedBrowser a{
+ color: #02e;
+ cursor: pointer;
+ text-decoration: none;
+}
+#unsupportedBrowser a:hover{
+ text-decoration: underline;
+}
+#unsupportedBrowser ul{
+ margin: 5px;
+}
+#unsupportedDetails{
+ display: none;
+ margin: 10px 50px 0 50px;
+ border: 3px solid #39a;
+ padding: 5px;
+ user-select: text;
+}
+#unsupportedHide{
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 50px;
+ height: 50px;
+ text-align: center;
+ line-height: 45px;
+ color: #777;
+ text-shadow: 1px 1px #fff;
+}
diff --git a/public/src/js/browsersupport.js b/public/src/js/browsersupport.js
new file mode 100644
index 0000000..6140086
--- /dev/null
+++ b/public/src/js/browsersupport.js
@@ -0,0 +1,107 @@
+function browserSupport(){
+ var tests = {
+ "Arrow function": function(){
+ eval("()=>{}")
+ return true
+ },
+ "AudioContext": function(){
+ return "AudioContext" in window || "webkitAudioContext" in window
+ },
+ "Class": function(){
+ eval("class a{}")
+ return true
+ },
+ "Array.find": function(){
+ return "find" in Array.prototype && "findIndex" in Array.prototype
+ },
+ "Path2D SVG": function(){
+ var canvas = document.createElement("canvas")
+ canvas.width = 1
+ canvas.height = 1
+ var ctx = canvas.getContext("2d")
+ var path = new Path2D("M0 0H1V1H0")
+ ctx.fill(path)
+ return ctx.getImageData(0, 0, 1, 1).data[3] !== 0
+ },
+ "Promise": function(){
+ if("Promise" in window && "resolve" in window.Promise && "reject" in window.Promise && "all" in window.Promise && "race" in window.Promise){
+ var resolve
+ new window.Promise(function(r){resolve = r})
+ return typeof resolve === "function"
+ }
+ },
+ "CSS Calc": function(){
+ var el = document.createElement("a")
+ el.style.width = "calc(1px)"
+ return el.style.length !== 0
+ }
+ }
+ var failedTests = []
+ for(var name in tests){
+ var result = false
+ try{
+ result = tests[name]()
+ }catch(e){}
+ if(result === false){
+ failedTests.push("
" + name + "")
+ }
+ }
+ if(failedTests.length !== 0){
+ var div = document.createElement("div")
+ div.id = "unsupportedBrowser"
+
+ div.innerHTML =
+'x
\
+You are running an unsupported browser (\
+Details...)\
+\
+The following tests have failed:\
+
'
++ failedTests.join("")
++ '
\
+Please use a supported browser such as \
+
Google Chrome\
+
'
+
+ document.body.appendChild(div)
+ var link = document.getElementById("unsupportedLink")
+ var details = document.getElementById("unsupportedDetails")
+ var hide = document.getElementById("unsupportedHide")
+ var chrome = document.getElementById("unsupportedChrome")
+ var divClick = function(event){
+ if(event.type === "touchstart"){
+ event.preventDefault()
+ getSelection().removeAllRanges()
+ }
+ div.classList.remove("hidden")
+ }
+ div.addEventListener("click", divClick)
+ div.addEventListener("touchstart", divClick)
+ var toggleDetails = function(event){
+ if(event.type === "touchstart"){
+ event.preventDefault()
+ }
+ if(details.style.display === "block"){
+ details.style.display = ""
+ }else{
+ details.style.display = "block"
+ }
+ }
+ link.addEventListener("click", toggleDetails)
+ link.addEventListener("touchstart", toggleDetails)
+ var hideClick = function(event){
+ if(event.type === "touchstart"){
+ event.preventDefault()
+ }
+ event.stopPropagation()
+ div.classList.add("hidden")
+ }
+ hide.addEventListener("click", hideClick)
+ hide.addEventListener("touchstart", hideClick)
+ chrome.addEventListener("touchend", function(event){
+ event.preventDefault()
+ chrome.click()
+ })
+ }
+}
+browserSupport()
diff --git a/public/src/js/loader.js b/public/src/js/loader.js
index af05129..fd2b52e 100644
--- a/public/src/js/loader.js
+++ b/public/src/js/loader.js
@@ -109,6 +109,13 @@ class Loader{
}
})
p2.send("invite", location.hash.slice(1).toLowerCase())
+ setTimeout(() => {
+ if(p2.socket.readyState !== 1){
+ p2.hash("")
+ p2.hashLock = false
+ resolve()
+ }
+ }, 10000)
}).then(() => {
pageEvents.remove(p2, "message")
}))
diff --git a/public/src/js/loadsong.js b/public/src/js/loadsong.js
index 32c0ee4..d840b50 100644
--- a/public/src/js/loadsong.js
+++ b/public/src/js/loadsong.js
@@ -115,14 +115,21 @@ class loadSong{
canvas.height = h
var ctx = canvas.getContext("2d")
ctx.drawImage(img, 0, 0, w, h)
- canvas.toBlob(blob => {
+ var saveScaled = url => {
let img2 = document.createElement("img")
pageEvents.load(img2).then(() => {
assets.image[filename] = img2
resolve()
}, reject)
- img2.src = URL.createObjectURL(blob)
- })
+ img2.src = url
+ }
+ if("toBlob" in canvas){
+ canvas.toBlob(blob => {
+ saveScaled(URL.createObjectURL(blob))
+ })
+ }else{
+ saveScaled(canvas.toDataURL())
+ }
}else{
assets.image[filename] = img
resolve()
diff --git a/public/src/js/main.js b/public/src/js/main.js
index ae427bd..6d9b00d 100644
--- a/public/src/js/main.js
+++ b/public/src/js/main.js
@@ -1,4 +1,4 @@
-addEventListener("error", err => {
+addEventListener("error", function(err){
var stack
if("error" in err){
stack = err.error.stack
@@ -109,3 +109,4 @@ if(location.hash.length === 6){
var loader = new Loader(() => {
new Titlescreen()
})
+
diff --git a/public/src/js/songselect.js b/public/src/js/songselect.js
index 4ab47bd..1099067 100644
--- a/public/src/js/songselect.js
+++ b/public/src/js/songselect.js
@@ -407,7 +407,7 @@ class SongSelect{
var mouse = this.mouseOffset(event.offsetX, event.offsetY)
var moveTo = null
if(this.state.screen === "song"){
- if(mouse.x > 641 && mouse.y > 603){
+ if(mouse.x > 641 && mouse.y > 603 && p2.socket.readyState === 1){
moveTo = "session"
}else{
var moveTo = this.songSelMouse(mouse.x, mouse.y)
@@ -591,8 +591,10 @@ class SongSelect{
assets.sounds["diffsel"].stop()
assets.sounds["don"].play()
- localStorage["selectedSong"] = this.selectedSong
- localStorage["selectedDiff"] = difficulty + this.diffOptions.length
+ try{
+ localStorage["selectedSong"] = this.selectedSong
+ localStorage["selectedDiff"] = difficulty + this.diffOptions.length
+ }catch(e){}
if(difficulty === 3 && this.state.ura){
difficulty = 4
@@ -623,7 +625,9 @@ class SongSelect{
if(!p2.session){
assets.sounds["ka"].play()
this.selectedDiff = 1
- this.state.options = this.mod(this.optionsList.length, this.state.options + moveBy)
+ do{
+ this.state.options = this.mod(this.optionsList.length, this.state.options + moveBy)
+ }while(p2.socket.readyState !== 1 && this.state.options === 2)
}
}
toTitleScreen(){
@@ -650,6 +654,9 @@ class SongSelect{
}, 500)
}
toSession(){
+ if(p2.socket.readyState !== 1){
+ return
+ }
if(p2.session){
p2.send("gameend")
}else{
@@ -1470,7 +1477,7 @@ class SongSelect{
ctx.lineTo(x + 4, y + 4)
ctx.lineTo(x + 4, y + h)
ctx.fill()
- if(screen !== "difficulty"){
+ if(screen !== "difficulty" && p2.socket.readyState === 1){
var elapsed = (ms - this.state.screenMS) % 3100
var fade = 1
if(!p2.session && screen === "song"){
diff --git a/public/src/js/view.js b/public/src/js/view.js
index 606b2d4..fac2c2e 100644
--- a/public/src/js/view.js
+++ b/public/src/js/view.js
@@ -961,6 +961,7 @@
var selectedSong = this.controller.selectedSong
var songSkinName = selectedSong.songSkin.name
+ var supportsBlend = "mixBlendMode" in songBg.style
if(selectedSong.category in this.categories){
var catId = this.categories[selectedSong.category].sort
@@ -972,7 +973,7 @@
if(!selectedSong.songSkin.song){
var id = selectedSong.songBg
songBg.classList.add("songbg-" + id)
- this.setLayers("bg_song_" + id, true)
+ this.setLayers("bg_song_" + id + (supportsBlend ? "" : "a"), supportsBlend)
}else if(selectedSong.songSkin.song !== "none"){
var notStatic = selectedSong.songSkin.song !== "static"
if(notStatic){
@@ -1456,10 +1457,14 @@
}
}
ontouch(event){
- for(let touch of event.changedTouches){
+ if(!("changedTouches" in event)){
+ event.changedTouches = [event]
+ }
+ for(var i = 0; i < event.changedTouches.length; i++){
+ var touch = event.changedTouches[i]
event.preventDefault()
if(this.controller.game.paused){
- var mouse = this.mouseOffset(event.touches[0].pageX, event.touches[0].pageY)
+ var mouse = this.mouseOffset(touch.pageX, touch.pageY)
var moveTo = this.pauseMouse(mouse.x, mouse.y)
if(moveTo !== null){
this.pauseConfirm(moveTo)
diff --git a/templates/index.html b/templates/index.html
index d704494..4d09a58 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -68,6 +68,7 @@
taiko-web (unknown version)
{% endif %}
+