diff --git a/client/components/app/Appbar.vue b/client/components/app/Appbar.vue
index e8b441a6..5a12c88c 100644
--- a/client/components/app/Appbar.vue
+++ b/client/components/app/Appbar.vue
@@ -11,6 +11,11 @@
+
+
upload
diff --git a/client/layouts/default.vue b/client/layouts/default.vue
index 1d3db799..8d1631d2 100644
--- a/client/layouts/default.vue
+++ b/client/layouts/default.vue
@@ -232,10 +232,40 @@ export default {
this.socket.on('download_failed', this.downloadFailed)
this.socket.on('download_killed', this.downloadKilled)
this.socket.on('download_expired', this.downloadExpired)
+ },
+ showUpdateToast(versionData) {
+ var ignoreVersion = localStorage.getItem('ignoreVersion')
+ var latestVersion = versionData.latestVersion
+
+ if (!ignoreVersion || ignoreVersion !== latestVersion) {
+ this.$toast.info(`Update is available!\nCheck release notes for v${versionData.latestVersion}`, {
+ position: 'top-center',
+ toastClassName: 'cursor-pointer',
+ bodyClassName: 'custom-class-1',
+ timeout: 20000,
+ closeOnClick: false,
+ draggable: false,
+ hideProgressBar: false,
+ onClick: () => {
+ window.open(versionData.githubTagUrl, '_blank')
+ },
+ onClose: () => {
+ localStorage.setItem('ignoreVersion', versionData.latestVersion)
+ }
+ })
+ } else {
+ console.warn(`Update is available but user chose to dismiss it! v${versionData.latestVersion}`)
+ }
}
},
mounted() {
this.initializeSocket()
+ this.$store
+ .dispatch('checkForUpdate')
+ .then((res) => {
+ if (res && res.hasUpdate) this.showUpdateToast(res)
+ })
+ .catch((err) => console.error(err))
if (this.$route.query.error) {
this.$toast.error(this.$route.query.error)
@@ -243,4 +273,10 @@ export default {
}
}
}
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/client/package.json b/client/package.json
index dc1154cb..008af1d8 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
{
"name": "audiobookshelf-client",
- "version": "1.1.8",
+ "version": "1.1.9",
"description": "Audiobook manager and player",
"main": "index.js",
"scripts": {
diff --git a/client/plugins/toast.js b/client/plugins/toast.js
index 24192c9d..498b00e7 100644
--- a/client/plugins/toast.js
+++ b/client/plugins/toast.js
@@ -7,4 +7,4 @@ const options = {
draggable: false
}
-Vue.use(Toast, options)
\ No newline at end of file
+Vue.use(Toast, options)
diff --git a/client/plugins/version.js b/client/plugins/version.js
new file mode 100644
index 00000000..c8518d26
--- /dev/null
+++ b/client/plugins/version.js
@@ -0,0 +1,59 @@
+import packagejson from '../package.json'
+import axios from 'axios'
+
+function parseSemver(ver) {
+ if (!ver) return null
+ var groups = ver.match(/^v((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/)
+ if (groups && groups.length > 6) {
+ var total = Number(groups[3]) * 100 + Number(groups[4]) * 10 + Number(groups[5])
+ if (isNaN(total)) {
+ console.warn('Invalid version total', groups[3], groups[4], groups[5])
+ return null
+ }
+ return {
+ total,
+ version: groups[2],
+ major: Number(groups[3]),
+ minor: Number(groups[4]),
+ patch: Number(groups[5]),
+ preRelease: groups[6] || null
+ }
+ } else {
+ console.warn('Invalid semver string', ver)
+ }
+ return null
+}
+export async function checkForUpdate() {
+ if (!packagejson.version) {
+ return
+ }
+ var currVerObj = parseSemver('v' + packagejson.version)
+ if (!currVerObj) {
+ console.error('Invalid version', packagejson.version)
+ return
+ }
+ var largestVer = null
+ await axios.get(`https://api.github.com/repos/advplyr/audiobookshelf/tags`).then((res) => {
+ var tags = res.data
+ if (tags && tags.length) {
+ tags.forEach((tag) => {
+ var verObj = parseSemver(tag.name)
+ if (verObj) {
+ if (!largestVer || largestVer.total < verObj.total) {
+ largestVer = verObj
+ }
+ }
+ })
+ }
+ })
+ if (!largestVer) {
+ console.error('No valid version tags to compare with')
+ return
+ }
+ return {
+ hasUpdate: largestVer.total > currVerObj.total,
+ latestVersion: largestVer.version,
+ githubTagUrl: `https://github.com/advplyr/audiobookshelf/releases/tag/v${largestVer.version}`,
+ currentVersion: currVerObj.version
+ }
+}
\ No newline at end of file
diff --git a/client/store/index.js b/client/store/index.js
index 688ad59f..5b193f8b 100644
--- a/client/store/index.js
+++ b/client/store/index.js
@@ -1,6 +1,7 @@
-import Vue from 'vue'
+import { checkForUpdate } from '@/plugins/version'
export const state = () => ({
+ versionData: null,
serverSettings: null,
streamAudiobook: null,
editModalTab: 'details',
@@ -39,10 +40,24 @@ export const actions = {
console.error('Failed to update server settings', error)
return false
})
+ },
+ checkForUpdate({ commit }) {
+ return checkForUpdate()
+ .then((res) => {
+ commit('setVersionData', res)
+ return res
+ })
+ .catch((error) => {
+ console.error('Update check failed', error)
+ return false
+ })
}
}
export const mutations = {
+ setVersionData(state, versionData) {
+ state.versionData = versionData
+ },
setServerSettings(state, settings) {
state.serverSettings = settings
},
diff --git a/package.json b/package.json
index 5580c6dc..80a763f0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "audiobookshelf",
- "version": "1.1.8",
+ "version": "1.1.9",
"description": "Self-hosted audiobook server for managing and playing audiobooks.",
"main": "index.js",
"scripts": {