Install sheperdjs and create tour giude in project.

This commit is contained in:
Laknima 2025-08-10 02:22:27 +00:00
parent 2116f60133
commit ee3fa2f427
6 changed files with 210 additions and 10 deletions

View file

@ -2,7 +2,7 @@
<div class="w-full h-16 bg-primary relative">
<div id="appbar" role="toolbar" aria-label="Appbar" class="absolute top-0 bottom-0 left-0 w-full h-full px-2 md:px-6 py-1 z-60">
<div class="flex h-full items-center">
<nuxt-link to="/">
<nuxt-link to="/" id="appbar-home-icon">
<img src="~static/icon.svg" :alt="$strings.ButtonHome" class="w-8 min-w-8 h-8 mr-2 sm:w-10 sm:min-w-10 sm:h-10 sm:mr-4" />
</nuxt-link>
@ -10,9 +10,9 @@
<h1 class="text-xl mr-6 hidden lg:block hover:underline">audiobookshelf</h1>
</nuxt-link>
<ui-libraries-dropdown class="mr-2" />
<ui-libraries-dropdown class="mr-2" id="appbar-library-icon" />
<controls-global-search v-if="currentLibrary" class="mr-1 sm:mr-0" />
<controls-global-search v-if="currentLibrary" class="mr-1 sm:mr-0" id="appbar-search-bar" ref="searchBar" />
<div class="grow" />
<ui-tooltip v-if="isChromecastInitialized && !isHttps" direction="bottom" text="Casting requires a secure connection" class="flex items-center">
@ -24,25 +24,33 @@
<widgets-notification-widget class="hidden md:block" />
<nuxt-link v-if="currentLibrary" to="/config/stats" class="hover:text-gray-200 cursor-pointer w-8 h-8 hidden sm:flex items-center justify-center mx-1">
<nuxt-link v-if="currentLibrary" to="/config/stats" id="appbar-stats" class="hover:text-gray-200 cursor-pointer w-8 h-8 hidden sm:flex items-center justify-center mx-1">
<ui-tooltip :text="$strings.HeaderYourStats" direction="bottom" class="flex items-center">
<span class="material-symbols text-2xl" aria-label="User Stats" role="button">&#xe01d;</span>
</ui-tooltip>
</nuxt-link>
<nuxt-link v-if="userCanUpload && currentLibrary" to="/upload" class="hover:text-gray-200 cursor-pointer w-8 h-8 flex items-center justify-center mx-1">
<nuxt-link v-if="userCanUpload && currentLibrary" to="/upload" id="appbar-upload-button" class="hover:text-gray-200 cursor-pointer w-8 h-8 flex items-center justify-center mx-1">
<ui-tooltip :text="$strings.ButtonUpload" direction="bottom" class="flex items-center">
<span class="material-symbols text-2xl" aria-label="Upload Media" role="button">&#xf09b;</span>
</ui-tooltip>
</nuxt-link>
<nuxt-link v-if="userIsAdminOrUp" to="/config" class="hover:text-gray-200 cursor-pointer w-8 h-8 flex items-center justify-center mx-1">
<nuxt-link v-if="userIsAdminOrUp" to="/config" id="appbar-settings-icon" class="hover:text-gray-200 cursor-pointer w-8 h-8 flex items-center justify-center mx-1">
<ui-tooltip :text="$strings.HeaderSettings" direction="bottom" class="flex items-center">
<span class="material-symbols text-2xl" aria-label="System Settings" role="button">&#xe8b8;</span>
</ui-tooltip>
</nuxt-link>
<nuxt-link to="/account" class="relative w-9 h-9 md:w-32 bg-fg border border-gray-500 rounded-sm shadow-xs ml-1.5 sm:ml-3 md:ml-5 md:pl-3 md:pr-10 py-2 text-left sm:text-sm cursor-pointer hover:bg-bg/40" aria-haspopup="listbox" aria-expanded="true">
<!-- Tour Tooltip icon -->
<ui-tooltip text="Start Tour" direction="bottom">
<button @click="startTour" class="hover:text-gray-200 w-8 h-8 flex items-center justify-center mx-1">
<span class="material-symbols text-2xl">info</span>
</button>
</ui-tooltip>
<!-- Tour Tooltip icon -->
<nuxt-link to="/account" id="appbar-account-link" class="relative w-9 h-9 md:w-32 bg-fg border border-gray-500 rounded-sm shadow-xs ml-1.5 sm:ml-3 md:ml-5 md:pl-3 md:pr-10 py-2 text-left sm:text-sm cursor-pointer hover:bg-bg/40" aria-haspopup="listbox" aria-expanded="true">
<span class="items-center hidden md:flex">
<span class="block truncate">{{ username }}</span>
</span>
@ -83,7 +91,13 @@
</div>
</template>
<script>
//import Shepherd from 'shepherd.js'
import Shepherd from 'shepherd.js'
import 'shepherd.js/dist/css/shepherd.css'
export default {
data() {
return {
@ -375,6 +389,107 @@ export default {
},
batchAutoMatchClick() {
this.$store.commit('globals/setShowBatchQuickMatchModal', true)
},
startTour() {
const tour = new Shepherd.Tour({
useModalOverlay: true,
defaultStepOptions: {
scrollTo: true,
cancelIcon: { enabled: true },
classes: 'shadow-md bg-primary text-white',
highlightClass: 'bg-secondary'
}
})
tour.addStep({
id: 'home-button',
text: 'Click here to return to the homepage.',
attachTo: {
element: '#appbar-home-icon',
on: 'bottom'
},
buttons: [{ text: 'Next', action: tour.next }]
})
tour.addStep({
id: 'library_icon',
text: 'Click to select the library',
attachTo: {
element: '#appbar-library-icon',
on: 'bottom'
},
buttons: [
{ text: 'Back', action: tour.back },
{ text: 'Next', action: tour.next }
]
})
tour.addStep({
id: 'search-bar',
text: 'Use this search bar to find any book.',
attachTo: {
element: '#appbar-search-bar',
on: 'bottom'
},
buttons: [
{ text: 'Back', action: tour.back },
{ text: 'Next', action: tour.next }
]
})
tour.addStep({
id: 'stats-icon',
text: 'View your stats here.',
attachTo: {
element: '#appbar-stats',
on: 'bottom'
},
buttons: [
{ text: 'Back', action: tour.back },
{ text: 'Next', action: tour.next }
]
})
tour.addStep({
id: 'upload-button',
text: 'Click here to upload a new audiobook.',
attachTo: {
element: '#appbar-upload-button',
on: 'bottom'
},
buttons: [
{ text: 'Back', action: tour.back },
{ text: 'Next', action: tour.next }
]
})
tour.addStep({
id: 'settings-icon',
text: 'Access your app settings here.',
attachTo: {
element: '#appbar-settings-icon',
on: 'bottom'
},
buttons: [
{ text: 'Back', action: tour.back },
{ text: 'Next', action: tour.next }
]
})
tour.addStep({
id: 'account-link',
text: 'Click here to access your account settings.',
attachTo: {
element: '#appbar-account-link',
on: 'bottom'
},
buttons: [
{ text: 'Back', action: tour.back },
{ text: 'Done', action: tour.complete }
]
})
tour.start()
}
},
mounted() {

View file

@ -39,11 +39,11 @@ module.exports = {
base: routerBasePath
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: ['@/assets/tailwind.css', '@/assets/app.css'],
// Global CSS: https://go.nuxtjs.dev/config-css
css: ['@/assets/tailwind.css', '@/assets/app.css', 'shepherd.js/dist/css/shepherd.css'],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: ['@/plugins/constants.js', '@/plugins/init.client.js', '@/plugins/axios.js', '@/plugins/toast.js', '@/plugins/utils.js', '@/plugins/i18n.js'],
plugins: ['@/plugins/constants.js', '@/plugins/init.client.js', '@/plugins/axios.js', '@/plugins/toast.js', '@/plugins/utils.js', '@/plugins/i18n.js', '~/plugins/tour.js'],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,

View file

@ -16,12 +16,14 @@
"core-js": "^3.16.0",
"cron-parser": "^4.7.1",
"date-fns": "^2.25.0",
"driver.js": "^1.3.6",
"epubjs": "^0.3.88",
"fast-average-color": "^9.4.0",
"hls.js": "^1.5.7",
"libarchive.js": "^1.3.0",
"nuxt": "^2.18.1",
"nuxt-socket-io": "^1.1.18",
"shepherd.js": "^14.5.1",
"trix": "^1.3.1",
"v-click-outside": "^3.1.2",
"vue-toastification": "^1.7.11",
@ -3090,6 +3092,28 @@
"node": ">=10.0.0"
}
},
"node_modules/@floating-ui/core": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
"dependencies": {
"@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.3.tgz",
"integrity": "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag==",
"dependencies": {
"@floating-ui/core": "^1.7.3",
"@floating-ui/utils": "^0.2.10"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
},
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
@ -4504,6 +4528,12 @@
"integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==",
"license": "MIT"
},
"node_modules/@scarf/scarf": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@scarf/scarf/-/scarf-1.4.0.tgz",
"integrity": "sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==",
"hasInstallScript": true
},
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
@ -8372,6 +8402,14 @@
"node": ">=0.10.0"
}
},
"node_modules/deepmerge-ts": {
"version": "7.1.5",
"resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz",
"integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==",
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@ -8614,6 +8652,11 @@
"url": "https://dotenvx.com"
}
},
"node_modules/driver.js": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/driver.js/-/driver.js-1.3.6.tgz",
"integrity": "sha512-g2nNuu+tWmPpuoyk3ffpT9vKhjPz4NrJzq6mkRDZIwXCrFhrKdDJ9TX5tJOBpvCTBrBYjgRQ17XlcQB15q4gMg=="
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@ -16641,6 +16684,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/shepherd.js": {
"version": "14.5.1",
"resolved": "https://registry.npmjs.org/shepherd.js/-/shepherd.js-14.5.1.tgz",
"integrity": "sha512-VuvPvLG1QjNOLP7AIm2HGyfmxEIz8QdskvWOHwUcxLDibYWjLRBmCWd8LSL5FlwhBW7D/GU+3gNVC/ASxAWdxg==",
"dependencies": {
"@floating-ui/dom": "^1.7.0",
"@scarf/scarf": "^1.4.0",
"deepmerge-ts": "^7.1.1"
},
"engines": {
"node": "18.* || >= 20"
}
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",

View file

@ -24,12 +24,14 @@
"core-js": "^3.16.0",
"cron-parser": "^4.7.1",
"date-fns": "^2.25.0",
"driver.js": "^1.3.6",
"epubjs": "^0.3.88",
"fast-average-color": "^9.4.0",
"hls.js": "^1.5.7",
"libarchive.js": "^1.3.0",
"nuxt": "^2.18.1",
"nuxt-socket-io": "^1.1.18",
"shepherd.js": "^14.5.1",
"trix": "^1.3.1",
"v-click-outside": "^3.1.2",
"vue-toastification": "^1.7.11",

View file

@ -6,6 +6,9 @@
</template>
<script>
import Shepherd from 'shepherd.js'
import 'shepherd.js/dist/css/shepherd.css'
export default {
async asyncData({ store, params, redirect }) {
const libraryId = params.library

24
client/plugins/tour.js Normal file
View file

@ -0,0 +1,24 @@
// client/plugins/tour.js
import Shepherd from 'shepherd.js'
import 'shepherd.js/dist/css/shepherd.css'
export default (context, inject) => {
const defaultTourOptions = {
defaultStepOptions: {
cancelIcon: {
enabled: true
},
scrollTo: { behavior: 'smooth', block: 'center' },
classes: 'shadow-md bg-purple-dark text-white rounded p-3'
},
useModalOverlay: true
}
const createTour = (steps = []) => {
const tour = new Shepherd.Tour(defaultTourOptions)
steps.forEach((step) => tour.addStep(step))
return tour
}
inject('createTour', createTour)
}