owntone / owntone-server

Linux/FreeBSD DAAP (iTunes) and MPD audio server with support for AirPlay 1 and 2 speakers (multiroom), Apple Remote (and compatibles), Chromecast, Spotify and internet radio.
https://owntone.github.io/owntone-server
GNU General Public License v2.0
2.05k stars 235 forks source link

[web] web interface does not load for IOS 9.x after web ui version 0.6.0 #1024

Closed whatdoineed2do closed 6 months ago

whatdoineed2do commented 4 years ago

@chme I recently noticed that the web interface no longer loads on an older ipad running IOS 9.3.5

I have explicitly added ios_saf references in web-src/.browserslistrc and rebuilt the web interface but still no joy

# browserslistrc 
> 0.25%
not ie <= 8
not dead
not op_mini all
ios_saf >= 9
safari >= 9

Any ideas how to make the web build support these older versions of IOS?

Running npx browserslist with local changes shows support - confg in master branch only supports ios_saf 12.0-12.1 and newer.

$ npx browserslist
and_chr 81
and_uc 12.12
chrome 80
chrome 79
chrome 78
chrome 49
edge 18
firefox 74
firefox 73
ie 11
ios_saf 13.3
ios_saf 13.2
ios_saf 13.0-13.1
ios_saf 12.2-12.4
ios_saf 12.0-12.1
ios_saf 11.3-11.4
ios_saf 11.0-11.2
ios_saf 10.3
ios_saf 10.0-10.2
ios_saf 9.3
ios_saf 9.0-9.2
opera 66
safari 13
safari 12.1
safari 12
safari 11.1
safari 11
safari 10.1
safari 10
safari 9.1
safari 9
samsung 11.1
samsung 10.1
chme commented 4 years ago

Do you see an error message (maybe in the js console) or does it not render at all?

whatdoineed2do commented 4 years ago

On the IOS device (ipad / old iphone 4) we're NOT able to get console info but it doesn't render at all - I can see the WiFi loading something but at the end its just a white/blank page.

I didn't dig too deep but Icouldn't figure out a way to see what agent string was sent by the client side - if you know how that can be enabled I might be able to dig a bit further but ios_saf 9.3 is in the list of supported browsers as per above output.

On a similar note, is it possible to put up a handler/message to display if a browser (and its agent name) is not supported? In those cases, people with really old browsers would at least get some info and if we figure out the above, people can rebuild the web ui themselves for the additional browser support.

chme commented 4 years ago

The .browserlistrc is used by the npm/webpack build of the web interface to identify what javascript version has to be supported. Newer (unsupported) javascript constructs are then transpilled into supported constructs. The list is not used server side to identify if a browser is supported.

With the current web interface, i activated the --modern build flag (https://cli.vuejs.org/guide/browser-compatibility.html#modern-mode), this creates two versions, one with transpilled JS and one without. Maybe on the iPad the logic that identifies if the transpilled version is needed does not work correctly.

To test this, can you remove the --modern flag from the build command in package.json?

whatdoineed2do commented 4 years ago

I removed --modern from package.json, deleted the node_modules and reinstalled but this still didn't work.

I walked the commits back in htdocs and found this commit, 4a28b8878af8bca73144c84631849e6a9abf8934, (0.6.0) was the last working version for IOS 9.3.x. I took this commit, cleared the local node_modules and rebuilt locally with my version of npm and the IOS 9.3.x device works.

Having a look at the changes between 0.6 and 0.7 in web-src dir theres nothing that jumps out in the config items:

$ git diff 4a28b8878af8bca73144c84631849e6a9abf8934..885cdf11f1b6762cbd0af2290e06602d4a97a184 ./web-src
diff --git a/web-src/.eslintrc.js b/web-src/.eslintrc.js
index 98d04316..e637c66c 100644
--- a/web-src/.eslintrc.js
+++ b/web-src/.eslintrc.js
@@ -3,7 +3,7 @@ module.exports = {
   env: {
     node: true
   },
-  'extends': [
+  extends: [
     'plugin:vue/essential',
     '@vue/standard'
   ],
diff --git a/web-src/babel.config.js b/web-src/babel.config.js
index ba179669..e9558405 100644
--- a/web-src/babel.config.js
+++ b/web-src/babel.config.js
@@ -1,5 +1,5 @@
 module.exports = {
   presets: [
-    '@vue/app'
+    '@vue/cli-plugin-babel/preset'
   ]
 }
diff --git a/web-src/package.json b/web-src/package.json
index 88fc2686..0bf16c54 100644
--- a/web-src/package.json
+++ b/web-src/package.json
@@ -1,39 +1,48 @@
 {
   "name": "forked-daapd-web",
-  "version": "0.6.0",
+  "version": "0.7.0",
+  "private": true,
   "description": "forked-daapd web interface",
   "author": "chme <christian.meffert@googlemail.com>",
-  "license": "GPL-2.0",
-  "private": true,
   "scripts": {
     "serve": "vue-cli-service serve",
-    "dev": "vue-cli-service serve",
-    "build": "vue-cli-service build --no-clean",
-    "lint": "vue-cli-service lint"
+    "build": "vue-cli-service build --no-clean --modern",
+    "lint": "vue-cli-service lint",
+    "dev": "vue-cli-service serve"
   },
   "dependencies": {
-    "axios": "^0.19.1",
-    "bulma": "^0.8.0",
+    "axios": "^0.19.2",
+    "bulma": "^0.8.2",
+    "core-js": "^3.6.5",
     "mdi": "^2.2.43",
     "moment": "^2.24.0",
     "moment-duration-format": "^2.3.2",
-    "npm": "^6.13.6",
+    "npm": "^6.14.4",
     "reconnectingwebsocket": "^1.0.0",
     "spotify-web-api-js": "^1.2.0",
-    "v-click-outside": "^3.0.0",
+    "string-to-color": "^2.1.3",
+    "v-click-outside": "^3.0.1",
     "vue": "^2.6.11",
-    "vue-infinite-loading": "^2.4.4",
+    "vue-infinite-loading": "^2.4.5",
     "vue-progressbar": "^0.7.5",
     "vue-range-slider": "^0.6.0",
-    "vue-router": "^3.1.3",
+    "vue-router": "^3.1.6",
     "vuedraggable": "^2.23.2",
-    "vuex": "^3.1.2"
+    "vuex": "^3.1.3"
   },
   "devDependencies": {
-    "@vue/cli-plugin-babel": "^3.12.1",
-    "@vue/cli-plugin-eslint": "^3.12.1",
-    "@vue/cli-service": "^3.12.1",
-    "@vue/eslint-config-standard": "^4.0.0",
+    "@vue/cli-plugin-babel": "^4.3.1",
+    "@vue/cli-plugin-eslint": "^4.3.1",
+    "@vue/cli-service": "^4.3.1",
+    "@vue/eslint-config-standard": "^5.1.2",
+    "babel-eslint": "^10.1.0",
+    "eslint": "^6.8.0",
+    "eslint-plugin-import": "^2.20.2",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-promise": "^4.2.1",
+    "eslint-plugin-standard": "^4.0.1",
+    "eslint-plugin-vue": "^6.2.2",
     "vue-template-compiler": "^2.6.11"
-  }
+  },
+  "license": "GPL-2.0"
 }
whatdoineed2do commented 4 years ago

I've done some more digging on this and it looks like its NOT the 0.6.0 to 0.7.x dependancies but rather something in the code.

I took master's web-src/package.json, stripped out the linter, and the 0.6.0 code (last working version for IOS 9.x) and built the UI and that worked.

{
  "name": "forked-daapd-web",
  "version": "0.7.1",
  "private": true,
  "description": "forked-daapd web interface",
  "author": "chme <christian.meffert@googlemail.com>",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --no-clean",
    "lint": "vue-cli-service lint",
    "dev": "vue-cli-service serve"
  },
  "dependencies": {
    "axios": "^0.19.2",
    "bulma": "^0.8.2",
    "core-js": "^3.6.5",
    "mdi": "^2.2.43",
    "moment": "^2.24.0",
    "moment-duration-format": "^2.3.2",
    "npm": "^6.14.4",
    "reconnectingwebsocket": "^1.0.0",
    "spotify-web-api-js": "^1.2.0",
    "string-to-color": "^2.1.3",
    "v-click-outside": "^3.0.1",
    "vue": "^2.6.11",
    "vue-infinite-loading": "^2.4.5",
    "vue-progressbar": "^0.7.5",
    "vue-range-slider": "^0.6.0",
    "vue-router": "^3.1.6",
    "vuedraggable": "^2.23.2",
    "vuex": "^3.1.3"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.3.1",
    "@vue/cli-service": "^4.3.1",
    "vue-template-compiler": "^2.6.11"
  },
  "license": "GPL-2.0"
}

However, when I use same package.json and bring back master's web-src dir and rebuild, IOS 9.x shows the white/blank screen.

I know there was a lot that changed between 0.6 and 0.7 but is there anything substantial in the code that changed that I could dig around?

$ git diff --name-only 4a28b8878af8bca73144c84631849e6a9abf8934..885cdf11f1b6762cbd0af2290e06602d4a97a184 .
web-src/.eslintrc.js
web-src/babel.config.js
web-src/package-lock.json
web-src/package.json
web-src/src/App.vue
web-src/src/components/CoverArtwork.vue
web-src/src/components/ListItemDirectory.vue
web-src/src/components/ListItemGenre.vue
web-src/src/components/ListItemQueueItem.vue
web-src/src/components/ModalDialog.vue
web-src/src/components/ModalDialogAddRss.vue
web-src/src/components/ModalDialogAddUrlStream.vue
web-src/src/components/ModalDialogAlbum.vue
web-src/src/components/ModalDialogArtist.vue
web-src/src/components/ModalDialogDirectory.vue
web-src/src/components/ModalDialogGenre.vue
web-src/src/components/ModalDialogPlaylist.vue
web-src/src/components/ModalDialogPlaylistSave.vue
web-src/src/components/ModalDialogQueueItem.vue
web-src/src/components/ModalDialogRemotePairing.vue
web-src/src/components/ModalDialogTrack.vue
web-src/src/components/NavbarBottom.vue
web-src/src/components/NavbarItemLink.vue
web-src/src/components/NavbarItemOutput.vue
web-src/src/components/NavbarTop.vue
web-src/src/components/PlayerButtonConsume.vue
web-src/src/components/PlayerButtonNext.vue
web-src/src/components/PlayerButtonPlayPause.vue
web-src/src/components/PlayerButtonPrevious.vue
web-src/src/components/PlayerButtonRepeat.vue
web-src/src/components/PlayerButtonSeekBack.vue
web-src/src/components/PlayerButtonSeekForward.vue
web-src/src/components/PlayerButtonShuffle.vue
web-src/src/components/SettingsCheckbox.vue
web-src/src/components/SettingsTextfield.vue
web-src/src/components/SpotifyModalDialogAlbum.vue
web-src/src/components/SpotifyModalDialogArtist.vue
web-src/src/components/SpotifyModalDialogPlaylist.vue
web-src/src/components/SpotifyModalDialogTrack.vue
web-src/src/components/TabsSettings.vue
web-src/src/lib/SVGRenderer.js
web-src/src/mystyles.css
web-src/src/pages/PageAbout.vue
web-src/src/pages/PageAlbum.vue
web-src/src/pages/PageAlbums.vue
web-src/src/pages/PageArtist.vue
web-src/src/pages/PageArtistTracks.vue
web-src/src/pages/PageArtists.vue
web-src/src/pages/PageAudiobook.vue
web-src/src/pages/PageAudiobooks.vue
web-src/src/pages/PageBrowse.vue
web-src/src/pages/PageBrowseRecentlyAdded.vue
web-src/src/pages/PageBrowseRecentlyPlayed.vue
web-src/src/pages/PageFiles.vue
web-src/src/pages/PageGenre.vue
web-src/src/pages/PageGenreTracks.vue
web-src/src/pages/PageGenres.vue
web-src/src/pages/PageNowPlaying.vue
web-src/src/pages/PagePlaylist.vue
web-src/src/pages/PagePlaylists.vue
web-src/src/pages/PagePodcast.vue
web-src/src/pages/PagePodcasts.vue
web-src/src/pages/PageQueue.vue
web-src/src/pages/PageSearch.vue
web-src/src/pages/SettingsPageArtwork.vue
web-src/src/pages/SettingsPageWebinterface.vue
web-src/src/pages/SpotifyPageAlbum.vue
web-src/src/pages/SpotifyPageArtist.vue
web-src/src/pages/SpotifyPageBrowse.vue
web-src/src/pages/SpotifyPageBrowseFeaturedPlaylists.vue
web-src/src/pages/SpotifyPageBrowseNewReleases.vue
web-src/src/pages/SpotifyPagePlaylist.vue
web-src/src/pages/SpotifyPageSearch.vue
web-src/src/router/index.js
web-src/src/store/index.js
web-src/src/store/mutation_types.js
web-src/src/webapi/index.js
chme commented 4 years ago

It seems to be possible to get the Javascript console output from an iOS Safari browser by connecting it to a desktop Safari browser: https://stackoverflow.com/questions/26014850/debugging-mobile-safari-in-ios-8-and-ios-9

It is hard to tell why it fails, due to the amount of changes. But if it fails directly on the first page, it has to be a change in the common parts: main.js, App.vue, NavbarTop.vue, NavbarBottom.vue, ...

whatdoineed2do commented 4 years ago

Darn. Only available on Mac (i only have access to linux and windows). I'll have to leave this to someone who has the same problem.

hacketiwack commented 1 year ago

@whatdoineed2do, are you still using a device with iOS 9? Shall we keep this issue open?

whatdoineed2do commented 1 year ago

i have an old ipad that was v useful as a remote - if this could be fixed, that woudl be more convienient than scrolling on my phone for sure

hacketiwack commented 1 year ago

My approach to test the behaviour you're facing:

As you can see, this is not especially straightforward. But certainly doable. Before I come to start the aforementioned steps, what model of iPad do you have?

whatdoineed2do commented 1 year ago

thanks - its an ipad 2

hacketiwack commented 1 year ago

I fiddled around with the debugger and the iPad 2 simulator with iOS 9. I've got the same result as you have: a white page. The page is properly loaded, but it seems no JavaScript is launched. No error is visible in the console.

The only errors I can see when I lint the code with eslint-plugin-compat are:

/owntone-server/web-src/src/audio.js
  13:26  error  AudioContext is not supported in iOS Safari 9.0-9.2  compat/compat

/owntone-server/web-src/src/lib/GroupByList.js
  139:4  error  Symbol.iterator() is not supported in iOS Safari 9.0-9.2  compat/compat
hacketiwack commented 6 months ago

I will close this issue mainly because it is nearly impossible to debug with this old version of iOS. Moreover, there will be plenty of other things that won't work because Safari on iOS 9 is very old; some HTML, CSS features are not supported and never will be (because it's not developed anymore).