mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-23 19:42:31 -05:00
[web] Change navigation bars
This commit is contained in:
parent
e0a2ab159e
commit
3d9cec4ded
430
web-src/package-lock.json
generated
430
web-src/package-lock.json
generated
@ -12,8 +12,7 @@
|
||||
"@mdi/js": "^7.4.47",
|
||||
"@ts-pro/vue-eternal-loading": "^1.3.1",
|
||||
"axios": "^1.7.4",
|
||||
"bulma": "^0.9.4",
|
||||
"bulma-switch": "^2.0.4",
|
||||
"bulma": "^1.0.2",
|
||||
"luxon": "^3.4.4",
|
||||
"mdi-vue": "^3.0.13",
|
||||
"pinia": "^2.1.7",
|
||||
@ -66,12 +65,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.4.tgz",
|
||||
"integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==",
|
||||
"version": "7.25.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
|
||||
"integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.25.4"
|
||||
"@babel/types": "^7.25.6"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@ -81,9 +80,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.25.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.4.tgz",
|
||||
"integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==",
|
||||
"version": "7.25.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
|
||||
"integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.24.8",
|
||||
@ -525,9 +524,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/config-array": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz",
|
||||
"integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==",
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
|
||||
"integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@ -564,9 +563,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "9.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz",
|
||||
"integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==",
|
||||
"version": "9.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz",
|
||||
"integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -583,6 +582,19 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/plugin-kit": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz",
|
||||
"integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"levn": "^0.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/module-importer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
|
||||
@ -798,9 +810,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz",
|
||||
"integrity": "sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.2.tgz",
|
||||
"integrity": "sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -812,9 +824,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.0.tgz",
|
||||
"integrity": "sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.2.tgz",
|
||||
"integrity": "sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -826,9 +838,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz",
|
||||
"integrity": "sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.2.tgz",
|
||||
"integrity": "sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -840,9 +852,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.0.tgz",
|
||||
"integrity": "sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.2.tgz",
|
||||
"integrity": "sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -854,9 +866,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.0.tgz",
|
||||
"integrity": "sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.2.tgz",
|
||||
"integrity": "sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -868,9 +880,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.0.tgz",
|
||||
"integrity": "sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.2.tgz",
|
||||
"integrity": "sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -882,9 +894,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.0.tgz",
|
||||
"integrity": "sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -896,9 +908,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.0.tgz",
|
||||
"integrity": "sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.2.tgz",
|
||||
"integrity": "sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -910,9 +922,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.0.tgz",
|
||||
"integrity": "sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@ -924,9 +936,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.0.tgz",
|
||||
"integrity": "sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@ -938,9 +950,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.0.tgz",
|
||||
"integrity": "sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@ -952,9 +964,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.0.tgz",
|
||||
"integrity": "sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.2.tgz",
|
||||
"integrity": "sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -966,9 +978,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.0.tgz",
|
||||
"integrity": "sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.2.tgz",
|
||||
"integrity": "sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -980,9 +992,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.0.tgz",
|
||||
"integrity": "sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.2.tgz",
|
||||
"integrity": "sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -994,9 +1006,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.0.tgz",
|
||||
"integrity": "sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.2.tgz",
|
||||
"integrity": "sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@ -1008,9 +1020,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz",
|
||||
"integrity": "sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.2.tgz",
|
||||
"integrity": "sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -1038,9 +1050,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vitejs/plugin-vue": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.2.tgz",
|
||||
"integrity": "sha512-nY9IwH12qeiJqumTCLJLE7IiNx7HZ39cbHaysEUd+Myvbz9KAqd2yq+U01Kab1R/H1BmiyM2ShTYlNH32Fzo3A==",
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.3.tgz",
|
||||
"integrity": "sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -1052,53 +1064,53 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.38.tgz",
|
||||
"integrity": "sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.3.tgz",
|
||||
"integrity": "sha512-adAfy9boPkP233NTyvLbGEqVuIfK/R0ZsBsIOW4BZNfb4BRpRW41Do1u+ozJpsb+mdoy80O20IzAsHaihRb5qA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.24.7",
|
||||
"@vue/shared": "3.4.38",
|
||||
"@babel/parser": "^7.25.3",
|
||||
"@vue/shared": "3.5.3",
|
||||
"entities": "^4.5.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.38.tgz",
|
||||
"integrity": "sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.3.tgz",
|
||||
"integrity": "sha512-wnzFArg9zpvk/811CDOZOadJRugf1Bgl/TQ3RfV4nKfSPok4hi0w10ziYUQR6LnnBAUlEXYLUfZ71Oj9ds/+QA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.4.38",
|
||||
"@vue/shared": "3.4.38"
|
||||
"@vue/compiler-core": "3.5.3",
|
||||
"@vue/shared": "3.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.38.tgz",
|
||||
"integrity": "sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.3.tgz",
|
||||
"integrity": "sha512-P3uATLny2tfyvMB04OQFe7Sczteno7SLFxwrOA/dw01pBWQHB5HL15a8PosoNX2aG/EAMGqnXTu+1LnmzFhpTQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.24.7",
|
||||
"@vue/compiler-core": "3.4.38",
|
||||
"@vue/compiler-dom": "3.4.38",
|
||||
"@vue/compiler-ssr": "3.4.38",
|
||||
"@vue/shared": "3.4.38",
|
||||
"@babel/parser": "^7.25.3",
|
||||
"@vue/compiler-core": "3.5.3",
|
||||
"@vue/compiler-dom": "3.5.3",
|
||||
"@vue/compiler-ssr": "3.5.3",
|
||||
"@vue/shared": "3.5.3",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.10",
|
||||
"postcss": "^8.4.40",
|
||||
"magic-string": "^0.30.11",
|
||||
"postcss": "^8.4.44",
|
||||
"source-map-js": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.38.tgz",
|
||||
"integrity": "sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.3.tgz",
|
||||
"integrity": "sha512-F/5f+r2WzL/2YAPl7UlKcJWHrvoZN8XwEBLnT7S4BXwncH25iDOabhO2M2DWioyTguJAGavDOawejkFXj8EM1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.4.38",
|
||||
"@vue/shared": "3.4.38"
|
||||
"@vue/compiler-dom": "3.5.3",
|
||||
"@vue/shared": "3.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-api": {
|
||||
@ -1108,53 +1120,53 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.38.tgz",
|
||||
"integrity": "sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.3.tgz",
|
||||
"integrity": "sha512-2w61UnRWTP7+rj1H/j6FH706gRBHdFVpIqEkSDAyIpafBXYH8xt4gttstbbCWdU3OlcSWO8/3mbKl/93/HSMpw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.4.38"
|
||||
"@vue/shared": "3.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-core": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.38.tgz",
|
||||
"integrity": "sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.3.tgz",
|
||||
"integrity": "sha512-5b2AQw5OZlmCzSsSBWYoZOsy75N4UdMWenTfDdI5bAzXnuVR7iR8Q4AOzQm2OGoA41xjk53VQKrqQhOz2ktWaw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.4.38",
|
||||
"@vue/shared": "3.4.38"
|
||||
"@vue/reactivity": "3.5.3",
|
||||
"@vue/shared": "3.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-dom": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.38.tgz",
|
||||
"integrity": "sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.3.tgz",
|
||||
"integrity": "sha512-wPR1DEGc3XnQ7yHbmkTt3GoY0cEnVGQnARRdAkDzZ8MbUKEs26gogCQo6AOvvgahfjIcnvWJzkZArQ1fmWjcSg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.4.38",
|
||||
"@vue/runtime-core": "3.4.38",
|
||||
"@vue/shared": "3.4.38",
|
||||
"@vue/reactivity": "3.5.3",
|
||||
"@vue/runtime-core": "3.5.3",
|
||||
"@vue/shared": "3.5.3",
|
||||
"csstype": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.38.tgz",
|
||||
"integrity": "sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.3.tgz",
|
||||
"integrity": "sha512-28volmaZVG2PGO3V3+gBPKoSHvLlE8FGfG/GKXKkjjfxLuj/50B/0OQGakM/g6ehQeqCrZYM4eHC4Ks48eig1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-ssr": "3.4.38",
|
||||
"@vue/shared": "3.4.38"
|
||||
"@vue/compiler-ssr": "3.5.3",
|
||||
"@vue/shared": "3.5.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.4.38"
|
||||
"vue": "3.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/shared": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.38.tgz",
|
||||
"integrity": "sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.3.tgz",
|
||||
"integrity": "sha512-Jp2v8nylKBT+PlOUjun2Wp/f++TfJVFjshLzNtJDdmFJabJa7noGMncqXRM1vXGX+Yo2V7WykQFNxusSim8SCA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
@ -1251,9 +1263,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
|
||||
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
|
||||
"version": "1.7.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@ -1313,15 +1325,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bulma": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz",
|
||||
"integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bulma-switch": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/bulma-switch/-/bulma-switch-2.0.4.tgz",
|
||||
"integrity": "sha512-kMu4H0Pr0VjvfsnT6viRDCgptUq0Rvy7y7PX6q+IHg1xUynsjszPjhAdal5ysAlCG5HNO+5YXxeiu92qYGQolw==",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.2.tgz",
|
||||
"integrity": "sha512-D7GnDuF6seb6HkcnRMM9E739QpEY9chDzzeFrHMyEns/EXyDJuQ0XA0KxbBl/B2NTsKSoDomW61jFGFaAxhK5A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/callsites": {
|
||||
@ -1481,13 +1487,13 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
|
||||
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
@ -1601,17 +1607,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "9.9.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz",
|
||||
"integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==",
|
||||
"version": "9.10.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz",
|
||||
"integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.11.0",
|
||||
"@eslint/config-array": "^0.17.1",
|
||||
"@eslint/config-array": "^0.18.0",
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "9.9.0",
|
||||
"@eslint/js": "9.10.0",
|
||||
"@eslint/plugin-kit": "^0.1.0",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@humanwhocodes/retry": "^0.3.0",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
@ -1634,7 +1641,6 @@
|
||||
"is-glob": "^4.0.0",
|
||||
"is-path-inside": "^3.0.3",
|
||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||
"levn": "^0.4.1",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"minimatch": "^3.1.2",
|
||||
"natural-compare": "^1.4.0",
|
||||
@ -1674,9 +1680,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-vue": {
|
||||
"version": "9.27.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.27.0.tgz",
|
||||
"integrity": "sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==",
|
||||
"version": "9.28.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.28.0.tgz",
|
||||
"integrity": "sha512-ShrihdjIhOTxs+MfWun6oJWuk+g/LAhN+CiuOl/jjkG3l0F2AuK5NMTaWqyvBgkFtpYmyks6P4603mLmhNJW8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -1685,7 +1691,7 @@
|
||||
"natural-compare": "^1.4.0",
|
||||
"nth-check": "^2.1.1",
|
||||
"postcss-selector-parser": "^6.0.15",
|
||||
"semver": "^7.6.0",
|
||||
"semver": "^7.6.3",
|
||||
"vue-eslint-parser": "^9.4.3",
|
||||
"xml-name-validator": "^4.0.0"
|
||||
},
|
||||
@ -1952,9 +1958,9 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@ -2336,9 +2342,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
|
||||
"integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -2397,9 +2403,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@ -2542,9 +2548,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
@ -2613,9 +2619,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-types": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.3.tgz",
|
||||
"integrity": "sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz",
|
||||
"integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -2625,9 +2631,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.41",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
|
||||
"integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
|
||||
"version": "8.4.45",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz",
|
||||
"integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@ -2770,9 +2776,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz",
|
||||
"integrity": "sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==",
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.2.tgz",
|
||||
"integrity": "sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -2786,22 +2792,22 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.21.0",
|
||||
"@rollup/rollup-android-arm64": "4.21.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.21.0",
|
||||
"@rollup/rollup-darwin-x64": "4.21.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.21.0",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.21.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.21.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.21.0",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.21.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.21.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.21.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.21.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.21.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.21.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.21.0",
|
||||
"@rollup/rollup-android-arm-eabi": "4.21.2",
|
||||
"@rollup/rollup-android-arm64": "4.21.2",
|
||||
"@rollup/rollup-darwin-arm64": "4.21.2",
|
||||
"@rollup/rollup-darwin-x64": "4.21.2",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.21.2",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.21.2",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.21.2",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.21.2",
|
||||
"@rollup/rollup-linux-x64-musl": "4.21.2",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.21.2",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.21.2",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.21.2",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@ -2830,9 +2836,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.77.8",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz",
|
||||
"integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==",
|
||||
"version": "1.78.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.78.0.tgz",
|
||||
"integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -2901,9 +2907,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@ -3017,19 +3023,25 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unplugin": {
|
||||
"version": "1.12.2",
|
||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.12.2.tgz",
|
||||
"integrity": "sha512-bEqQxeC7rxtxPZ3M5V4Djcc4lQqKPgGe3mAWZvxcSmX5jhGxll19NliaRzQSQPrk4xJZSGniK3puLWpRuZN7VQ==",
|
||||
"version": "1.13.1",
|
||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.13.1.tgz",
|
||||
"integrity": "sha512-6Kq1iSSwg7KyjcThRUks9LuqDAKvtnioxbL9iEtB9ctTyBA5OmrB8gZd/d225VJu1w3UpUsKV7eGrvf59J7+VA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.12.1",
|
||||
"chokidar": "^3.6.0",
|
||||
"webpack-sources": "^3.2.3",
|
||||
"webpack-virtual-modules": "^0.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"webpack-sources": "^3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"webpack-sources": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/uri-js": {
|
||||
@ -3050,14 +3062,14 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.4.2",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
|
||||
"integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz",
|
||||
"integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.21.3",
|
||||
"postcss": "^8.4.41",
|
||||
"postcss": "^8.4.43",
|
||||
"rollup": "^4.20.0"
|
||||
},
|
||||
"bin": {
|
||||
@ -3110,16 +3122,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vue": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.38.tgz",
|
||||
"integrity": "sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==",
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.3.tgz",
|
||||
"integrity": "sha512-xvRbd0HpuLovYbOHXRHlSBsSvmUJbo0pzbkKTApWnQGf3/cu5Z39mQeA5cZdLRVIoNf3zI6MSoOgHUT5i2jO+Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.4.38",
|
||||
"@vue/compiler-sfc": "3.4.38",
|
||||
"@vue/runtime-dom": "3.4.38",
|
||||
"@vue/server-renderer": "3.4.38",
|
||||
"@vue/shared": "3.4.38"
|
||||
"@vue/compiler-dom": "3.5.3",
|
||||
"@vue/compiler-sfc": "3.5.3",
|
||||
"@vue/runtime-dom": "3.5.3",
|
||||
"@vue/server-renderer": "3.5.3",
|
||||
"@vue/shared": "3.5.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
@ -3300,16 +3312,6 @@
|
||||
"vue": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-sources": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-virtual-modules": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
||||
@ -3354,9 +3356,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
|
||||
"integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz",
|
||||
"integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
|
@ -16,8 +16,7 @@
|
||||
"@mdi/js": "^7.4.47",
|
||||
"@ts-pro/vue-eternal-loading": "^1.3.1",
|
||||
"axios": "^1.7.4",
|
||||
"bulma": "^0.9.4",
|
||||
"bulma-switch": "^2.0.4",
|
||||
"bulma": "^1.0.2",
|
||||
"luxon": "^3.4.4",
|
||||
"mdi-vue": "^3.0.13",
|
||||
"pinia": "^2.1.7",
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a class="navbar-item" :href="href" @click.stop.prevent="open">
|
||||
<a :href="href" @click.stop.prevent="open">
|
||||
<slot />
|
||||
</a>
|
||||
</template>
|
||||
@ -8,7 +8,7 @@
|
||||
import { useUIStore } from '@/stores/ui'
|
||||
|
||||
export default {
|
||||
name: 'NavbarItemLink',
|
||||
name: 'ControlLink',
|
||||
props: {
|
||||
to: { required: true, type: Object }
|
||||
},
|
62
web-src/src/components/ControlMainVolume.vue
Normal file
62
web-src/src/components/ControlMainVolume.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="media is-align-items-center pt-0">
|
||||
<div class="media-left">
|
||||
<a class="button is-white is-small" @click="toggle">
|
||||
<mdicon class="icon" :name="icon" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<p class="heading" v-text="$t('navigation.volume')" />
|
||||
<control-slider
|
||||
v-model:value="player.volume"
|
||||
:cursor="cursor"
|
||||
:max="100"
|
||||
@change="changeVolume"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ControlSlider from '@/components/ControlSlider.vue'
|
||||
import { mdiCancel } from '@mdi/js'
|
||||
import { usePlayerStore } from '@/stores/player'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'ControlVolume',
|
||||
components: { ControlSlider },
|
||||
setup() {
|
||||
return {
|
||||
player: usePlayerStore()
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
cursor: mdiCancel,
|
||||
old_volume: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
icon() {
|
||||
return this.player.volume > 0 ? 'volume-high' : 'volume-off'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'player.volume'() {
|
||||
if (this.player.volume > 0) {
|
||||
this.old_volume = this.player.volume
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeVolume(value) {
|
||||
webapi.player_volume(this.player.volume)
|
||||
},
|
||||
toggle() {
|
||||
this.player.volume = this.player.volume > 0 ? 0 : this.old_volume
|
||||
this.changeVolume()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
79
web-src/src/components/ControlOutputVolume.vue
Normal file
79
web-src/src/components/ControlOutputVolume.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="media is-align-items-center pt-0">
|
||||
<div class="media-left">
|
||||
<a
|
||||
class="button is-white is-small"
|
||||
:class="{ 'has-text-grey-light': !output.selected }"
|
||||
@click="toggle"
|
||||
>
|
||||
<mdicon class="icon" :name="icon" :title="output.type" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<p
|
||||
class="heading"
|
||||
:class="{ 'has-text-grey-light': !output.selected }"
|
||||
v-text="output.name"
|
||||
/>
|
||||
<control-slider
|
||||
v-model:value="volume"
|
||||
:disabled="!output.selected"
|
||||
:max="100"
|
||||
:cursor="cursor"
|
||||
@change="changeVolume"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ControlSlider from '@/components/ControlSlider.vue'
|
||||
import { mdiCancel } from '@mdi/js'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'ControlOutputVolume',
|
||||
components: {
|
||||
ControlSlider
|
||||
},
|
||||
props: { output: { required: true, type: Object } },
|
||||
|
||||
data() {
|
||||
return {
|
||||
cursor: mdiCancel,
|
||||
volume: this.output.selected ? this.output.volume : 0
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
icon() {
|
||||
if (this.output.type.startsWith('AirPlay')) {
|
||||
return 'cast-variant'
|
||||
} else if (this.output.type === 'Chromecast') {
|
||||
return 'cast'
|
||||
} else if (this.output.type === 'fifo') {
|
||||
return 'pipe'
|
||||
}
|
||||
return 'server'
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
output() {
|
||||
this.volume = this.output.volume
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
changeVolume() {
|
||||
webapi.player_output_volume(this.output.id, this.volume)
|
||||
},
|
||||
toggle() {
|
||||
const values = {
|
||||
selected: !this.output.selected
|
||||
}
|
||||
webapi.output_update(this.output.id, values)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<a v-if="visible" :disabled="disabled" @click="seek">
|
||||
<mdicon
|
||||
class="icon"
|
||||
name="rewind-10"
|
||||
:size="icon_size"
|
||||
:title="$t('player.button.seek-backward')"
|
||||
/>
|
||||
</a>
|
||||
@ -14,10 +14,9 @@ import { useQueueStore } from '@/stores/queue'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonSeekBack',
|
||||
name: 'ControlPlayerBack',
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number },
|
||||
seek_ms: { required: true, type: Number }
|
||||
offset: { required: true, type: Number }
|
||||
},
|
||||
|
||||
setup() {
|
||||
@ -52,7 +51,7 @@ export default {
|
||||
methods: {
|
||||
seek() {
|
||||
if (!this.disabled) {
|
||||
webapi.player_seek(this.seek_ms * -1)
|
||||
webapi.player_seek(this.offset * -1)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<a :class="{ 'is-info': is_consume }" @click="toggle_consume_mode">
|
||||
<a :class="{ 'is-info': is_consume }" @click="toggle">
|
||||
<mdicon
|
||||
class="icon"
|
||||
name="fire"
|
||||
:size="icon_size"
|
||||
size="16"
|
||||
:title="$t('player.button.consume')"
|
||||
/>
|
||||
</a>
|
||||
@ -14,10 +14,7 @@ import { usePlayerStore } from '@/stores/player'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonConsume',
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number }
|
||||
},
|
||||
name: 'ControlPlayerConsume',
|
||||
|
||||
setup() {
|
||||
return {
|
||||
@ -32,11 +29,9 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggle_consume_mode() {
|
||||
toggle() {
|
||||
webapi.player_consume(!this.is_consume)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<a v-if="visible" :disabled="disabled" @click="seek">
|
||||
<mdicon
|
||||
class="icon"
|
||||
name="fast-forward-30"
|
||||
:size="icon_size"
|
||||
:title="$t('player.button.seek-forward')"
|
||||
/>
|
||||
</a>
|
||||
@ -14,10 +14,9 @@ import { useQueueStore } from '@/stores/queue'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonSeekForward',
|
||||
name: 'ControlPlayerForward',
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number },
|
||||
seek_ms: { required: true, type: Number }
|
||||
offset: { required: true, type: Number }
|
||||
},
|
||||
|
||||
setup() {
|
||||
@ -52,7 +51,7 @@ export default {
|
||||
methods: {
|
||||
seek() {
|
||||
if (!this.disabled) {
|
||||
webapi.player_seek(this.seek_ms)
|
||||
webapi.player_seek(this.offset)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<a :class="{ 'is-info': is_active }" @click="toggle_lyrics">
|
||||
<a :class="{ 'is-info': is_active }" @click="toggle">
|
||||
<mdicon
|
||||
class="icon"
|
||||
:name="icon_name"
|
||||
:size="icon_size"
|
||||
:name="icon"
|
||||
:size="16"
|
||||
:title="$t('player.button.toggle-lyrics')"
|
||||
/>
|
||||
</a>
|
||||
@ -13,10 +13,7 @@
|
||||
import { useLyricsStore } from '@/stores/lyrics'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonLyrics',
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number }
|
||||
},
|
||||
name: 'ControlPlayerLyrics',
|
||||
|
||||
setup() {
|
||||
return {
|
||||
@ -25,7 +22,7 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
icon_name() {
|
||||
icon() {
|
||||
return this.is_active ? 'script-text-play' : 'script-text-outline'
|
||||
},
|
||||
is_active() {
|
||||
@ -34,11 +31,9 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggle_lyrics() {
|
||||
toggle() {
|
||||
this.lyricsStore.pane = !this.lyricsStore.pane
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<a :disabled="disabled" @click="play_next">
|
||||
<mdicon
|
||||
class="icon"
|
||||
name="skip-forward"
|
||||
:size="icon_size"
|
||||
:title="$t('player.button.skip-forward')"
|
||||
/>
|
||||
</a>
|
||||
@ -13,10 +13,7 @@ import { useQueueStore } from '@/stores/queue'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonNext',
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number }
|
||||
},
|
||||
name: 'ControlPlayerNext',
|
||||
|
||||
computed: {
|
||||
disabled() {
|
||||
@ -29,11 +26,8 @@ export default {
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
|
||||
webapi.player_next()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,10 +1,6 @@
|
||||
<template>
|
||||
<a :disabled="disabled" @click="toggle_play_pause">
|
||||
<mdicon
|
||||
:name="icon_name"
|
||||
:size="icon_size"
|
||||
:title="$t(`player.button.${icon_name}`)"
|
||||
/>
|
||||
<a :disabled="disabled" @click="toggle">
|
||||
<mdicon class="icon" :name="icon" :title="$t(`player.button.${icon}`)" />
|
||||
</a>
|
||||
</template>
|
||||
|
||||
@ -15,9 +11,8 @@ import { useQueueStore } from '@/stores/queue'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonPlayPause',
|
||||
name: 'ControlPlayerPlay',
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number },
|
||||
show_disabled_message: Boolean
|
||||
},
|
||||
|
||||
@ -33,7 +28,7 @@ export default {
|
||||
disabled() {
|
||||
return this.queueStore?.count <= 0
|
||||
},
|
||||
icon_name() {
|
||||
icon() {
|
||||
if (!this.is_playing) {
|
||||
return 'play'
|
||||
} else if (this.is_pause_allowed) {
|
||||
@ -51,7 +46,7 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggle_play_pause() {
|
||||
toggle() {
|
||||
if (this.disabled) {
|
||||
if (this.show_disabled_message) {
|
||||
this.notificationsStore.add({
|
||||
@ -74,5 +69,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<a :disabled="disabled" @click="play_previous">
|
||||
<mdicon
|
||||
class="icon"
|
||||
name="skip-backward"
|
||||
:size="icon_size"
|
||||
:title="$t('player.button.skip-backward')"
|
||||
/>
|
||||
</a>
|
||||
@ -13,10 +13,7 @@ import { useQueueStore } from '@/stores/queue'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonPrevious',
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number }
|
||||
},
|
||||
name: 'ControlPlayerPrevious',
|
||||
|
||||
setup() {
|
||||
return {
|
||||
@ -40,5 +37,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<a :class="{ 'is-info': !is_repeat_off }" @click="toggle_repeat_mode">
|
||||
<a :class="{ 'is-info': !is_repeat_off }" @click="toggle">
|
||||
<mdicon
|
||||
class="icon"
|
||||
:name="icon_name"
|
||||
:size="icon_size"
|
||||
:title="$t(`player.button.${icon_name}`)"
|
||||
:name="icon"
|
||||
:size="16"
|
||||
:title="$t(`player.button.${icon}`)"
|
||||
/>
|
||||
</a>
|
||||
</template>
|
||||
@ -14,19 +14,14 @@ import { usePlayerStore } from '@/stores/player'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonRepeat',
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number }
|
||||
},
|
||||
|
||||
name: 'ControlPlayerRepeat',
|
||||
setup() {
|
||||
return {
|
||||
playerStore: usePlayerStore()
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
icon_name() {
|
||||
icon() {
|
||||
if (this.is_repeat_all) {
|
||||
return 'repeat'
|
||||
} else if (this.is_repeat_single) {
|
||||
@ -46,7 +41,7 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggle_repeat_mode() {
|
||||
toggle() {
|
||||
if (this.is_repeat_all) {
|
||||
webapi.player_repeat('single')
|
||||
} else if (this.is_repeat_single) {
|
||||
@ -58,5 +53,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<a :class="{ 'is-info': is_shuffle }" @click="toggle_shuffle_mode">
|
||||
<a :class="{ 'is-info': is_shuffle }" @click="toggle">
|
||||
<mdicon
|
||||
class="icon"
|
||||
:name="icon_name"
|
||||
:size="icon_size"
|
||||
:title="$t(`player.button.${icon_name}`)"
|
||||
:name="icon"
|
||||
:size="16"
|
||||
:title="$t(`player.button.${icon}`)"
|
||||
/>
|
||||
</a>
|
||||
</template>
|
||||
@ -14,20 +14,14 @@ import { usePlayerStore } from '@/stores/player'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'PlayerButtonShuffle',
|
||||
|
||||
props: {
|
||||
icon_size: { default: 16, type: Number }
|
||||
},
|
||||
|
||||
name: 'ControlPlayerShuffle',
|
||||
setup() {
|
||||
return {
|
||||
playerStore: usePlayerStore()
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
icon_name() {
|
||||
icon() {
|
||||
if (this.is_shuffle) {
|
||||
return 'shuffle'
|
||||
}
|
||||
@ -37,13 +31,10 @@ export default {
|
||||
return this.playerStore.shuffle
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggle_shuffle_mode() {
|
||||
toggle() {
|
||||
webapi.player_shuffle(!this.is_shuffle)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
110
web-src/src/components/ControlStreamVolume.vue
Normal file
110
web-src/src/components/ControlStreamVolume.vue
Normal file
@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div class="media is-align-items-center pt-0">
|
||||
<div class="media-left">
|
||||
<a
|
||||
class="button is-white is-small"
|
||||
:class="{
|
||||
'has-text-grey-light': !playing && !loading,
|
||||
'is-loading': loading
|
||||
}"
|
||||
@click="togglePlay"
|
||||
>
|
||||
<mdicon class="icon" name="broadcast" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<div
|
||||
class="is-flex is-align-content-center"
|
||||
:class="{ 'has-text-grey-light': !playing }"
|
||||
>
|
||||
<p class="heading" v-text="$t('navigation.stream')" />
|
||||
<a href="stream.mp3" class="heading ml-2" target="_blank">
|
||||
<mdicon class="icon is-small" name="open-in-new" />
|
||||
</a>
|
||||
</div>
|
||||
<control-slider
|
||||
v-model:value="volume"
|
||||
:cursor="cursor"
|
||||
:disabled="!playing"
|
||||
:max="100"
|
||||
@change="changeVolume"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ControlSlider from '@/components/ControlSlider.vue'
|
||||
import audio from '@/lib/Audio'
|
||||
import { mdiCancel } from '@mdi/js'
|
||||
|
||||
export default {
|
||||
name: 'ControlStreamVolume',
|
||||
components: { ControlSlider },
|
||||
emits: ['change', 'mute'],
|
||||
data() {
|
||||
return {
|
||||
cursor: mdiCancel,
|
||||
loading: false,
|
||||
playing: false,
|
||||
volume: 10
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.setupAudio()
|
||||
},
|
||||
unmounted() {
|
||||
this.closeAudio()
|
||||
},
|
||||
methods: {
|
||||
changeVolume() {
|
||||
audio.setVolume(this.volume / 100)
|
||||
},
|
||||
closeAudio() {
|
||||
audio.stop()
|
||||
this.playing = false
|
||||
},
|
||||
playChannel() {
|
||||
if (this.playing) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
audio.play('/stream.mp3')
|
||||
audio.setVolume(this.volume / 100)
|
||||
},
|
||||
setupAudio() {
|
||||
const a = audio.setup()
|
||||
a.addEventListener('waiting', () => {
|
||||
this.playing = false
|
||||
this.loading = true
|
||||
})
|
||||
a.addEventListener('playing', () => {
|
||||
this.playing = true
|
||||
this.loading = false
|
||||
})
|
||||
a.addEventListener('ended', () => {
|
||||
this.playing = false
|
||||
this.loading = false
|
||||
})
|
||||
a.addEventListener('error', () => {
|
||||
this.closeAudio()
|
||||
this.notificationsStore.add({
|
||||
text: this.$t('navigation.stream-error'),
|
||||
type: 'danger'
|
||||
})
|
||||
this.playing = false
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
togglePlay() {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
if (this.playing) {
|
||||
this.closeAudio()
|
||||
}
|
||||
this.playChannel()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -223,4 +223,14 @@ export default {
|
||||
.lyrics div:last-child {
|
||||
padding-bottom: calc(25vh - 3rem);
|
||||
}
|
||||
|
||||
/* Lyrics animation */
|
||||
@keyframes pop-color {
|
||||
0% {
|
||||
color: var(--bulma-black);
|
||||
}
|
||||
100% {
|
||||
color: var(--bulma-success);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,116 +1,24 @@
|
||||
<template>
|
||||
<nav
|
||||
class="navbar is-block is-white is-fixed-bottom fd-bottom-navbar"
|
||||
:class="{
|
||||
'is-transparent': is_now_playing_page,
|
||||
'is-dark': !is_now_playing_page
|
||||
}"
|
||||
role="navigation"
|
||||
aria-label="player controls"
|
||||
class="navbar is-fixed-bottom"
|
||||
:class="{ 'is-dark': !is_now_playing_page }"
|
||||
>
|
||||
<!-- Player menu for desktop -->
|
||||
<div
|
||||
class="navbar-item has-dropdown has-dropdown-up is-hidden-touch"
|
||||
:class="{ 'is-active': show_player_menu }"
|
||||
>
|
||||
<div class="navbar-dropdown is-right fd-width-auto">
|
||||
<div class="navbar-item">
|
||||
<!-- Outputs: master volume -->
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left is-flex-grow-1">
|
||||
<div class="level-item is-flex-grow-0">
|
||||
<a class="button is-white is-small" @click="toggle_mute_volume">
|
||||
<mdicon
|
||||
class="icon"
|
||||
:name="player.volume > 0 ? 'volume-high' : 'volume-off'"
|
||||
size="18"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div>
|
||||
<p class="heading" v-text="$t('navigation.volume')" />
|
||||
<control-slider
|
||||
v-model:value="player.volume"
|
||||
:max="100"
|
||||
@change="change_volume"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Outputs: master volume -->
|
||||
<hr class="my-3" />
|
||||
<navbar-item-output
|
||||
v-for="output in outputs"
|
||||
:key="output.id"
|
||||
:output="output"
|
||||
/>
|
||||
<!-- Outputs: stream volume -->
|
||||
<hr class="my-3" />
|
||||
<div class="navbar-item">
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left is-flex-grow-1">
|
||||
<div class="level-item is-flex-grow-0">
|
||||
<a
|
||||
class="button is-white is-small"
|
||||
:class="{
|
||||
'has-text-grey-light': !playing && !loading,
|
||||
'is-loading': loading
|
||||
}"
|
||||
@click="togglePlay"
|
||||
>
|
||||
<mdicon class="icon" name="broadcast" size="18" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="is-flex-grow-1">
|
||||
<div
|
||||
class="is-flex is-align-content-center"
|
||||
:class="{ 'has-text-grey-light': !playing }"
|
||||
>
|
||||
<p class="heading" v-text="$t('navigation.stream')" />
|
||||
<a href="stream.mp3" class="heading ml-2" target="_blank">
|
||||
<mdicon
|
||||
class="icon is-small"
|
||||
name="open-in-new"
|
||||
size="16"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<control-slider
|
||||
v-model:value="stream_volume"
|
||||
:disabled="!playing"
|
||||
:max="100"
|
||||
:cursor="cursor"
|
||||
@change="change_stream_volume"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-3" />
|
||||
<div class="navbar-item is-justify-content-center">
|
||||
<div class="buttons has-addons">
|
||||
<player-button-repeat class="button" />
|
||||
<player-button-shuffle class="button" />
|
||||
<player-button-consume class="button" />
|
||||
<player-button-lyrics class="button" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-brand is-flex-grow-1">
|
||||
<navbar-item-link :to="{ name: 'queue' }" class="mr-auto">
|
||||
<mdicon class="icon" name="playlist-play" size="24" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link
|
||||
v-if="!is_now_playing_page"
|
||||
<control-link class="navbar-item" :to="{ name: 'queue' }">
|
||||
<mdicon class="icon" name="playlist-play" />
|
||||
</control-link>
|
||||
<template v-if="is_now_playing_page">
|
||||
<control-player-previous class="navbar-item ml-auto" />
|
||||
<control-player-back class="navbar-item" :offset="10000" />
|
||||
<control-player-play class="navbar-item" show_disabled_message />
|
||||
<control-player-forward class="navbar-item" :offset="30000" />
|
||||
<control-player-next class="navbar-item mr-auto" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<control-link
|
||||
:to="{ name: 'now-playing' }"
|
||||
exact
|
||||
class="is-expanded is-clipped is-size-7"
|
||||
class="navbar-item is-expanded is-clipped is-size-7"
|
||||
>
|
||||
<div class="fd-is-text-clipped">
|
||||
<strong v-text="current.title" />
|
||||
@ -121,130 +29,46 @@
|
||||
v-text="$t('navigation.now-playing', { album: current.album })"
|
||||
/>
|
||||
</div>
|
||||
</navbar-item-link>
|
||||
<player-button-previous
|
||||
v-if="is_now_playing_page"
|
||||
class="navbar-item px-2"
|
||||
:icon_size="24"
|
||||
/>
|
||||
<player-button-seek-back
|
||||
v-if="is_now_playing_page"
|
||||
:seek_ms="10000"
|
||||
class="navbar-item px-2"
|
||||
:icon_size="24"
|
||||
/>
|
||||
<player-button-play-pause
|
||||
class="navbar-item px-2"
|
||||
:icon_size="36"
|
||||
show_disabled_message
|
||||
/>
|
||||
<player-button-seek-forward
|
||||
v-if="is_now_playing_page"
|
||||
:seek_ms="30000"
|
||||
class="navbar-item px-2"
|
||||
:icon_size="24"
|
||||
/>
|
||||
<player-button-next
|
||||
v-if="is_now_playing_page"
|
||||
class="navbar-item px-2"
|
||||
:icon_size="24"
|
||||
/>
|
||||
</control-link>
|
||||
<control-player-play class="navbar-item" show_disabled_message />
|
||||
</template>
|
||||
<a
|
||||
class="navbar-item ml-auto"
|
||||
@click="show_player_menu = !show_player_menu"
|
||||
class="navbar-item"
|
||||
@click="uiStore.show_player_menu = !uiStore.show_player_menu"
|
||||
>
|
||||
<mdicon
|
||||
class="icon"
|
||||
:name="show_player_menu ? 'chevron-down' : 'chevron-up'"
|
||||
:name="uiStore.show_player_menu ? 'chevron-down' : 'chevron-up'"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<!-- Player menu for mobile and tablet -->
|
||||
<div
|
||||
class="navbar-menu is-hidden-desktop"
|
||||
:class="{ 'is-active': show_player_menu }"
|
||||
class="dropdown is-up is-right"
|
||||
:class="{ 'is-active': uiStore.show_player_menu }"
|
||||
>
|
||||
<div class="navbar-item">
|
||||
<div class="buttons has-addons is-centered">
|
||||
<player-button-repeat class="button" />
|
||||
<player-button-shuffle class="button" />
|
||||
<player-button-consume class="button" />
|
||||
<player-button-lyrics class="button" />
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content">
|
||||
<div class="dropdown-item">
|
||||
<control-main-volume />
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-3" />
|
||||
<!-- Outputs: master volume -->
|
||||
<div class="navbar-item">
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left is-flex-grow-1">
|
||||
<div class="level-item is-flex-grow-0">
|
||||
<a class="button is-white is-small" @click="toggle_mute_volume">
|
||||
<mdicon
|
||||
class="icon"
|
||||
:name="player.volume > 0 ? 'volume-high' : 'volume-off'"
|
||||
size="18"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="is-flex-grow-1">
|
||||
<p class="heading" v-text="$t('navigation.volume')" />
|
||||
<control-slider
|
||||
v-model:value="player.volume"
|
||||
:max="100"
|
||||
@change="change_volume"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-3" />
|
||||
<!-- Outputs: speaker volumes -->
|
||||
<navbar-item-output
|
||||
v-for="output in outputs"
|
||||
<hr class="dropdown-divider" />
|
||||
<div class="dropdown-item">
|
||||
<control-output-volume
|
||||
v-for="output in outputsStore.outputs"
|
||||
:key="output.id"
|
||||
:output="output"
|
||||
/>
|
||||
<!-- Outputs: stream volume -->
|
||||
<hr class="my-3" />
|
||||
<div class="navbar-item mb-5">
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left is-flex-grow-1">
|
||||
<div class="level-item is-flex-grow-0">
|
||||
<a
|
||||
class="button is-white is-small"
|
||||
:class="{
|
||||
'has-text-grey-light': !playing && !loading,
|
||||
'is-loading': loading
|
||||
}"
|
||||
@click="togglePlay"
|
||||
>
|
||||
<mdicon class="icon" name="radio-tower" size="16" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="is-flex-grow-1">
|
||||
<div
|
||||
class="is-flex is-align-content-center"
|
||||
:class="{ 'has-text-grey-light': !playing }"
|
||||
>
|
||||
<p class="heading" v-text="$t('navigation.stream')" />
|
||||
<a href="stream.mp3" class="heading ml-2" target="_blank">
|
||||
<mdicon
|
||||
class="icon is-small"
|
||||
name="open-in-new"
|
||||
size="16"
|
||||
/>
|
||||
</a>
|
||||
<hr class="dropdown-divider" />
|
||||
<div class="dropdown-item">
|
||||
<control-stream-volume />
|
||||
</div>
|
||||
<control-slider
|
||||
v-model:value="stream_volume"
|
||||
:disabled="!playing"
|
||||
:max="100"
|
||||
:cursor="cursor"
|
||||
@change="change_stream_volume"
|
||||
/>
|
||||
<hr class="dropdown-divider" />
|
||||
<div class="dropdown-item is-flex is-justify-content-center">
|
||||
<div class="buttons has-addons">
|
||||
<control-player-repeat class="button" />
|
||||
<control-player-shuffle class="button" />
|
||||
<control-player-consume class="button" />
|
||||
<control-player-lyrics class="button" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -255,168 +79,58 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ControlSlider from '@/components/ControlSlider.vue'
|
||||
import NavbarItemLink from '@/components/NavbarItemLink.vue'
|
||||
import NavbarItemOutput from '@/components/NavbarItemOutput.vue'
|
||||
import PlayerButtonConsume from '@/components/PlayerButtonConsume.vue'
|
||||
import PlayerButtonLyrics from '@/components/PlayerButtonLyrics.vue'
|
||||
import PlayerButtonNext from '@/components/PlayerButtonNext.vue'
|
||||
import PlayerButtonPlayPause from '@/components/PlayerButtonPlayPause.vue'
|
||||
import PlayerButtonPrevious from '@/components/PlayerButtonPrevious.vue'
|
||||
import PlayerButtonRepeat from '@/components/PlayerButtonRepeat.vue'
|
||||
import PlayerButtonSeekBack from '@/components/PlayerButtonSeekBack.vue'
|
||||
import PlayerButtonSeekForward from '@/components/PlayerButtonSeekForward.vue'
|
||||
import PlayerButtonShuffle from '@/components/PlayerButtonShuffle.vue'
|
||||
import audio from '@/lib/Audio'
|
||||
import { mdiCancel } from '@mdi/js'
|
||||
import ControlLink from '@/components/ControlLink.vue'
|
||||
import ControlMainVolume from '@/components/ControlMainVolume.vue'
|
||||
import ControlOutputVolume from '@/components/ControlOutputVolume.vue'
|
||||
import ControlPlayerBack from '@/components/ControlPlayerBack.vue'
|
||||
import ControlPlayerConsume from '@/components/ControlPlayerConsume.vue'
|
||||
import ControlPlayerForward from '@/components/ControlPlayerForward.vue'
|
||||
import ControlPlayerLyrics from '@/components/ControlPlayerLyrics.vue'
|
||||
import ControlPlayerNext from '@/components/ControlPlayerNext.vue'
|
||||
import ControlPlayerPlay from '@/components/ControlPlayerPlay.vue'
|
||||
import ControlPlayerPrevious from '@/components/ControlPlayerPrevious.vue'
|
||||
import ControlPlayerRepeat from '@/components/ControlPlayerRepeat.vue'
|
||||
import ControlPlayerShuffle from '@/components/ControlPlayerShuffle.vue'
|
||||
import ControlStreamVolume from '@/components/ControlStreamVolume.vue'
|
||||
import { useNotificationsStore } from '@/stores/notifications'
|
||||
import { useOutputsStore } from '@/stores/outputs'
|
||||
import { usePlayerStore } from '@/stores/player'
|
||||
import { useQueueStore } from '@/stores/queue'
|
||||
import { useUIStore } from '@/stores/ui'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'NavbarBottom',
|
||||
components: {
|
||||
ControlSlider,
|
||||
NavbarItemLink,
|
||||
NavbarItemOutput,
|
||||
PlayerButtonConsume,
|
||||
PlayerButtonLyrics,
|
||||
PlayerButtonNext,
|
||||
PlayerButtonPlayPause,
|
||||
PlayerButtonPrevious,
|
||||
PlayerButtonRepeat,
|
||||
PlayerButtonSeekBack,
|
||||
PlayerButtonSeekForward,
|
||||
PlayerButtonShuffle
|
||||
ControlLink,
|
||||
ControlOutputVolume,
|
||||
ControlMainVolume,
|
||||
ControlPlayerBack,
|
||||
ControlPlayerConsume,
|
||||
ControlPlayerForward,
|
||||
ControlPlayerLyrics,
|
||||
ControlPlayerNext,
|
||||
ControlPlayerPlay,
|
||||
ControlPlayerPrevious,
|
||||
ControlPlayerRepeat,
|
||||
ControlPlayerShuffle,
|
||||
ControlStreamVolume
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
notificationsStore: useNotificationsStore(),
|
||||
outputsStore: useOutputsStore(),
|
||||
playerStore: usePlayerStore(),
|
||||
queueStore: useQueueStore(),
|
||||
uiStore: useUIStore()
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
cursor: mdiCancel,
|
||||
loading: false,
|
||||
old_volume: 0,
|
||||
playing: false,
|
||||
show_desktop_outputs_menu: false,
|
||||
show_outputs_menu: false,
|
||||
stream_volume: 10
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
is_now_playing_page() {
|
||||
return this.$route.name === 'now-playing'
|
||||
},
|
||||
current() {
|
||||
return this.queueStore.current
|
||||
},
|
||||
outputs() {
|
||||
return this.outputsStore.outputs
|
||||
},
|
||||
player() {
|
||||
return this.playerStore
|
||||
},
|
||||
show_player_menu: {
|
||||
get() {
|
||||
return this.uiStore.show_player_menu
|
||||
},
|
||||
set(value) {
|
||||
this.uiStore.show_player_menu = value
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'playerStore.volume'() {
|
||||
if (this.player.volume > 0) {
|
||||
this.old_volume = this.player.volume
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// On app mounted
|
||||
mounted() {
|
||||
this.setupAudio()
|
||||
},
|
||||
|
||||
// On app destroyed
|
||||
unmounted() {
|
||||
this.closeAudio()
|
||||
},
|
||||
|
||||
methods: {
|
||||
change_stream_volume() {
|
||||
audio.setVolume(this.stream_volume / 100)
|
||||
},
|
||||
change_volume() {
|
||||
webapi.player_volume(this.player.volume)
|
||||
},
|
||||
closeAudio() {
|
||||
audio.stop()
|
||||
this.playing = false
|
||||
},
|
||||
on_click_outside_outputs() {
|
||||
this.show_outputs_menu = false
|
||||
},
|
||||
playChannel() {
|
||||
if (this.playing) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
audio.play('/stream.mp3')
|
||||
audio.setVolume(this.stream_volume / 100)
|
||||
},
|
||||
setupAudio() {
|
||||
const a = audio.setup()
|
||||
a.addEventListener('waiting', () => {
|
||||
this.playing = false
|
||||
this.loading = true
|
||||
})
|
||||
a.addEventListener('playing', () => {
|
||||
this.playing = true
|
||||
this.loading = false
|
||||
})
|
||||
a.addEventListener('ended', () => {
|
||||
this.playing = false
|
||||
this.loading = false
|
||||
})
|
||||
a.addEventListener('error', () => {
|
||||
this.closeAudio()
|
||||
this.notificationsStore.add({
|
||||
text: this.$t('navigation.stream-error'),
|
||||
type: 'danger'
|
||||
})
|
||||
this.playing = false
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
togglePlay() {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
if (this.playing) {
|
||||
this.closeAudio()
|
||||
}
|
||||
this.playChannel()
|
||||
},
|
||||
toggle_mute_volume() {
|
||||
this.player.volume = this.player.volume > 0 ? 0 : this.old_volume
|
||||
this.change_volume()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<div class="navbar-item">
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left is-flex-grow-1">
|
||||
<div class="level-item is-flex-grow-0">
|
||||
<a
|
||||
class="button is-white is-small"
|
||||
:class="{ 'has-text-grey-light': !output.selected }"
|
||||
@click="set_enabled"
|
||||
>
|
||||
<mdicon
|
||||
class="icon"
|
||||
:name="type_class"
|
||||
size="18"
|
||||
:title="output.type"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="is-flex-grow-1">
|
||||
<p
|
||||
class="heading"
|
||||
:class="{ 'has-text-grey-light': !output.selected }"
|
||||
v-text="output.name"
|
||||
/>
|
||||
<control-slider
|
||||
v-model:value="volume"
|
||||
:disabled="!output.selected"
|
||||
:max="100"
|
||||
:cursor="cursor"
|
||||
@change="change_volume"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ControlSlider from '@/components/ControlSlider.vue'
|
||||
import { mdiCancel } from '@mdi/js'
|
||||
import webapi from '@/webapi'
|
||||
|
||||
export default {
|
||||
name: 'NavbarItemOutput',
|
||||
components: {
|
||||
ControlSlider
|
||||
},
|
||||
props: { output: { required: true, type: Object } },
|
||||
|
||||
data() {
|
||||
return {
|
||||
cursor: mdiCancel,
|
||||
volume: this.output.selected ? this.output.volume : 0
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
type_class() {
|
||||
if (this.output.type.startsWith('AirPlay')) {
|
||||
return 'cast-variant'
|
||||
} else if (this.output.type === 'Chromecast') {
|
||||
return 'cast'
|
||||
} else if (this.output.type === 'fifo') {
|
||||
return 'pipe'
|
||||
}
|
||||
return 'server'
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
output() {
|
||||
this.volume = this.output.volume
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
change_volume() {
|
||||
webapi.player_output_volume(this.output.id, this.volume)
|
||||
},
|
||||
|
||||
set_enabled() {
|
||||
const values = {
|
||||
selected: !this.output.selected
|
||||
}
|
||||
webapi.output_update(this.output.id, values)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -6,126 +6,148 @@
|
||||
aria-label="main navigation"
|
||||
>
|
||||
<div class="navbar-brand">
|
||||
<navbar-item-link
|
||||
<control-link
|
||||
v-if="settingsStore.show_menu_item_playlists"
|
||||
class="navbar-item"
|
||||
:to="{ name: 'playlists' }"
|
||||
>
|
||||
<mdicon class="icon" name="music-box-multiple" size="16" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link
|
||||
</control-link>
|
||||
<control-link
|
||||
v-if="settingsStore.show_menu_item_music"
|
||||
class="navbar-item"
|
||||
:to="{ name: 'music' }"
|
||||
>
|
||||
<mdicon class="icon" name="music" size="16" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link
|
||||
</control-link>
|
||||
<control-link
|
||||
v-if="settingsStore.show_menu_item_podcasts"
|
||||
class="navbar-item"
|
||||
:to="{ name: 'podcasts' }"
|
||||
>
|
||||
<mdicon class="icon" name="microphone" size="16" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link
|
||||
</control-link>
|
||||
<control-link
|
||||
v-if="settingsStore.show_menu_item_audiobooks"
|
||||
class="navbar-item"
|
||||
:to="{ name: 'audiobooks' }"
|
||||
>
|
||||
<mdicon class="icon" name="book-open-variant" size="16" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link
|
||||
</control-link>
|
||||
<control-link
|
||||
v-if="settingsStore.show_menu_item_radio"
|
||||
class="navbar-item"
|
||||
:to="{ name: 'radio' }"
|
||||
>
|
||||
<mdicon class="icon" name="radio" size="16" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link
|
||||
</control-link>
|
||||
<control-link
|
||||
v-if="settingsStore.show_menu_item_files"
|
||||
class="navbar-item"
|
||||
:to="{ name: 'files' }"
|
||||
>
|
||||
<mdicon class="icon" name="folder-open" size="16" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link
|
||||
</control-link>
|
||||
<control-link
|
||||
v-if="settingsStore.show_menu_item_search"
|
||||
class="navbar-item"
|
||||
:to="{ name: searchStore.search_source }"
|
||||
>
|
||||
<mdicon class="icon" name="magnify" size="16" />
|
||||
</navbar-item-link>
|
||||
<div
|
||||
class="navbar-burger"
|
||||
:class="{ 'is-active': show_burger_menu }"
|
||||
@click="show_burger_menu = !show_burger_menu"
|
||||
>
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
</control-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-menu" :class="{ 'is-active': show_burger_menu }">
|
||||
<div class="navbar-start" />
|
||||
<div class="navbar-end">
|
||||
<!-- Burger menu entries -->
|
||||
<div
|
||||
class="navbar-item has-dropdown is-hoverable"
|
||||
:class="{ 'is-active': show_settings_menu }"
|
||||
@click="on_click_outside_settings"
|
||||
<a
|
||||
class="navbar-item"
|
||||
@click="uiStore.show_burger_menu = !uiStore.show_burger_menu"
|
||||
>
|
||||
<a class="navbar-item is-arrowless is-hidden-touch">
|
||||
<mdicon class="icon" name="menu" size="24" />
|
||||
<mdicon
|
||||
class="icon"
|
||||
:name="uiStore.show_burger_menu ? 'close' : 'menu'"
|
||||
/>
|
||||
</a>
|
||||
<div class="navbar-dropdown is-right">
|
||||
<navbar-item-link :to="{ name: 'playlists' }">
|
||||
<div
|
||||
class="dropdown is-right"
|
||||
:class="{ 'is-active': uiStore.show_burger_menu }"
|
||||
>
|
||||
<div class="dropdown-menu">
|
||||
<div class="dropdown-content">
|
||||
<control-link class="dropdown-item" :to="{ name: 'playlists' }">
|
||||
<span class="icon-text">
|
||||
<mdicon class="icon" name="music-box-multiple" size="16" />
|
||||
</span>
|
||||
<b v-text="$t('navigation.playlists')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: 'music' }">
|
||||
</control-link>
|
||||
<control-link class="dropdown-item" :to="{ name: 'music' }">
|
||||
<span class="icon-text">
|
||||
<mdicon class="icon" name="music" size="16" />
|
||||
</span>
|
||||
<b v-text="$t('navigation.music')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: 'music-artists' }">
|
||||
</control-link>
|
||||
<control-link class="dropdown-item" :to="{ name: 'music-artists' }">
|
||||
<span class="pl-5" v-text="$t('navigation.artists')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: 'music-albums' }">
|
||||
</control-link>
|
||||
<control-link class="dropdown-item" :to="{ name: 'music-albums' }">
|
||||
<span class="pl-5" v-text="$t('navigation.albums')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: 'music-genres' }">
|
||||
</control-link>
|
||||
<control-link class="dropdown-item" :to="{ name: 'music-genres' }">
|
||||
<span class="pl-5" v-text="$t('navigation.genres')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link
|
||||
</control-link>
|
||||
<control-link
|
||||
class="dropdown-item"
|
||||
v-if="spotify_enabled"
|
||||
:to="{ name: 'music-spotify' }"
|
||||
>
|
||||
<span class="pl-5" v-text="$t('navigation.spotify')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: 'podcasts' }">
|
||||
</control-link>
|
||||
<control-link class="dropdown-item" :to="{ name: 'podcasts' }">
|
||||
<span class="icon-text">
|
||||
<mdicon class="icon" name="microphone" size="16" />
|
||||
</span>
|
||||
<b v-text="$t('navigation.podcasts')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: 'audiobooks' }">
|
||||
</control-link>
|
||||
<control-link class="dropdown-item" :to="{ name: 'audiobooks' }">
|
||||
<span class="icon-text">
|
||||
<mdicon class="icon" name="book-open-variant" size="16" />
|
||||
</span>
|
||||
<b v-text="$t('navigation.audiobooks')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: 'radio' }">
|
||||
</control-link>
|
||||
<control-link class="dropdown-item" :to="{ name: 'radio' }">
|
||||
<span class="icon-text">
|
||||
<mdicon class="icon" name="radio" size="16" />
|
||||
</span>
|
||||
<b v-text="$t('navigation.radio')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: 'files' }">
|
||||
</control-link>
|
||||
<control-link class="dropdown-item" :to="{ name: 'files' }">
|
||||
<span class="icon-text">
|
||||
<mdicon class="icon" name="folder-open" size="16" />
|
||||
</span>
|
||||
<b v-text="$t('navigation.files')" />
|
||||
</navbar-item-link>
|
||||
<navbar-item-link :to="{ name: searchStore.search_source }">
|
||||
</control-link>
|
||||
<control-link
|
||||
class="dropdown-item"
|
||||
:to="{ name: searchStore.search_source }"
|
||||
>
|
||||
<span class="icon-text">
|
||||
<mdicon class="icon" name="magnify" size="16" />
|
||||
</span>
|
||||
<b v-text="$t('navigation.search')" />
|
||||
</navbar-item-link>
|
||||
</control-link>
|
||||
<hr class="my-3" />
|
||||
<navbar-item-link :to="{ name: 'settings-webinterface' }">
|
||||
<control-link
|
||||
class="dropdown-item"
|
||||
:to="{ name: 'settings-webinterface' }"
|
||||
>
|
||||
{{ $t('navigation.settings') }}
|
||||
</navbar-item-link>
|
||||
</control-link>
|
||||
<a
|
||||
class="navbar-item"
|
||||
class="dropdown-item"
|
||||
@click.stop.prevent="open_update_dialog()"
|
||||
v-text="$t('navigation.update-library')"
|
||||
/>
|
||||
<navbar-item-link :to="{ name: 'about' }">
|
||||
<control-link class="dropdown-item" :to="{ name: 'about' }">
|
||||
{{ $t('navigation.about') }}
|
||||
</navbar-item-link>
|
||||
</control-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -139,7 +161,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavbarItemLink from '@/components/NavbarItemLink.vue'
|
||||
import ControlLink from '@/components/ControlLink.vue'
|
||||
import { useSearchStore } from '@/stores/search'
|
||||
import { useServicesStore } from '@/stores/services'
|
||||
import { useSettingsStore } from '@/stores/settings'
|
||||
@ -147,7 +169,7 @@ import { useUIStore } from '@/stores/ui'
|
||||
|
||||
export default {
|
||||
name: 'NavbarTop',
|
||||
components: { NavbarItemLink },
|
||||
components: { ControlLink },
|
||||
|
||||
setup() {
|
||||
return {
|
||||
@ -165,22 +187,6 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
show_burger_menu: {
|
||||
get() {
|
||||
return this.uiStore.show_burger_menu
|
||||
},
|
||||
set(value) {
|
||||
this.uiStore.show_burger_menu = value
|
||||
}
|
||||
},
|
||||
show_update_dialog: {
|
||||
get() {
|
||||
return this.uiStore.show_update_dialog
|
||||
},
|
||||
set(value) {
|
||||
this.uiStore.show_update_dialog = value
|
||||
}
|
||||
},
|
||||
spotify_enabled() {
|
||||
return this.servicesStore.spotify.webapi_token_valid
|
||||
},
|
||||
@ -203,12 +209,10 @@ export default {
|
||||
this.show_settings_menu = !this.show_settings_menu
|
||||
},
|
||||
open_update_dialog() {
|
||||
this.show_update_dialog = true
|
||||
this.uiStore.show_update_dialog = true
|
||||
this.show_settings_menu = false
|
||||
this.show_burger_menu = false
|
||||
this.uiStore.show_burger_menu = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
mdiChevronDown,
|
||||
mdiChevronLeft,
|
||||
mdiChevronUp,
|
||||
mdiClose,
|
||||
mdiContentSave,
|
||||
mdiDelete,
|
||||
mdiDeleteEmpty,
|
||||
@ -79,6 +80,7 @@ export const icons = {
|
||||
mdiChevronDown,
|
||||
mdiChevronLeft,
|
||||
mdiChevronUp,
|
||||
mdiClose,
|
||||
mdiContentSave,
|
||||
mdiDelete,
|
||||
mdiDeleteEmpty,
|
||||
|
@ -41,8 +41,7 @@ import PageSettingsRemotesOutputs from '@/pages/PageSettingsRemotesOutputs.vue'
|
||||
import PageSettingsWebinterface from '@/pages/PageSettingsWebinterface.vue'
|
||||
import { useUIStore } from '@/stores/ui'
|
||||
|
||||
const TOP_WITH_TABS = 140
|
||||
const TOP_WITHOUT_TABS = 110
|
||||
const TOP_WITH_TABS = 124
|
||||
|
||||
export const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
@ -70,7 +69,7 @@ export const router = createRouter({
|
||||
},
|
||||
{
|
||||
component: PageAlbums,
|
||||
meta: { has_index: true, has_tabs: true, show_progress: true },
|
||||
meta: { has_index: true, show_progress: true },
|
||||
name: 'music-albums',
|
||||
path: '/music/albums'
|
||||
},
|
||||
@ -88,7 +87,7 @@ export const router = createRouter({
|
||||
},
|
||||
{
|
||||
component: PageArtists,
|
||||
meta: { has_index: true, has_tabs: true, show_progress: true },
|
||||
meta: { has_index: true, show_progress: true },
|
||||
name: 'music-artists',
|
||||
path: '/music/artists'
|
||||
},
|
||||
@ -106,7 +105,7 @@ export const router = createRouter({
|
||||
},
|
||||
{
|
||||
component: PageAudiobooksAlbums,
|
||||
meta: { has_index: true, has_tabs: true, show_progress: true },
|
||||
meta: { has_index: true, show_progress: true },
|
||||
name: 'audiobooks-albums',
|
||||
path: '/audiobooks/albums'
|
||||
},
|
||||
@ -118,13 +117,13 @@ export const router = createRouter({
|
||||
},
|
||||
{
|
||||
component: PageAudiobooksArtists,
|
||||
meta: { has_index: true, has_tabs: true, show_progress: true },
|
||||
meta: { has_index: true, show_progress: true },
|
||||
name: 'audiobooks-artists',
|
||||
path: '/audiobooks/artists'
|
||||
},
|
||||
{
|
||||
component: PageAudiobooksGenres,
|
||||
meta: { has_index: true, has_tabs: true, show_progress: true },
|
||||
meta: { has_index: true, show_progress: true },
|
||||
name: 'audiobooks-genres',
|
||||
path: '/audiobooks/genres'
|
||||
},
|
||||
@ -140,55 +139,55 @@ export const router = createRouter({
|
||||
},
|
||||
{
|
||||
component: PageMusic,
|
||||
meta: { has_tabs: true, show_progress: true },
|
||||
meta: { show_progress: true },
|
||||
name: 'music-history',
|
||||
path: '/music/history'
|
||||
},
|
||||
{
|
||||
component: PageMusicRecentlyAdded,
|
||||
meta: { has_tabs: true, show_progress: true },
|
||||
meta: { show_progress: true },
|
||||
name: 'music-recently-added',
|
||||
path: '/music/recently-added'
|
||||
},
|
||||
{
|
||||
component: PageMusicRecentlyPlayed,
|
||||
meta: { has_tabs: true, show_progress: true },
|
||||
meta: { show_progress: true },
|
||||
name: 'music-recently-played',
|
||||
path: '/music/recently-played'
|
||||
},
|
||||
{
|
||||
component: PageMusicSpotify,
|
||||
meta: { has_tabs: true, show_progress: true },
|
||||
meta: { show_progress: true },
|
||||
name: 'music-spotify',
|
||||
path: '/music/spotify'
|
||||
},
|
||||
{
|
||||
component: PageMusicSpotifyFeaturedPlaylists,
|
||||
meta: { has_tabs: true, show_progress: true },
|
||||
meta: { show_progress: true },
|
||||
name: 'music-spotify-featured-playlists',
|
||||
path: '/music/spotify/featured-playlists'
|
||||
},
|
||||
{
|
||||
component: PageMusicSpotifyNewReleases,
|
||||
meta: { has_tabs: true, show_progress: true },
|
||||
meta: { show_progress: true },
|
||||
name: 'music-spotify-new-releases',
|
||||
path: '/music/spotify/new-releases'
|
||||
},
|
||||
{
|
||||
component: PageComposerAlbums,
|
||||
meta: { has_index: true, show_progress: true },
|
||||
meta: { show_progress: true },
|
||||
name: 'music-composer-albums',
|
||||
path: '/music/composers/:name/albums'
|
||||
},
|
||||
{
|
||||
component: PageComposerTracks,
|
||||
meta: { has_index: true, show_progress: true },
|
||||
meta: { show_progress: true },
|
||||
name: 'music-composer-tracks',
|
||||
path: '/music/composers/:name/tracks'
|
||||
},
|
||||
{
|
||||
component: PageComposers,
|
||||
meta: { has_index: true, has_tabs: true, show_progress: true },
|
||||
meta: { has_index: true, show_progress: true },
|
||||
name: 'music-composers',
|
||||
path: '/music/composers'
|
||||
},
|
||||
@ -212,7 +211,7 @@ export const router = createRouter({
|
||||
},
|
||||
{
|
||||
component: PageGenres,
|
||||
meta: { has_index: true, has_tabs: true, show_progress: true },
|
||||
meta: { has_index: true, show_progress: true },
|
||||
name: 'music-genres',
|
||||
path: '/music/genres'
|
||||
},
|
||||
@ -313,14 +312,13 @@ export const router = createRouter({
|
||||
* Staying on the same page and jumping to an anchor (e. g. index nav)
|
||||
* As there is no transition, there is no timeout added
|
||||
*/
|
||||
const top = to.meta.has_tabs ? TOP_WITH_TABS : TOP_WITHOUT_TABS
|
||||
return { behavior: 'smooth', el: to.hash, top }
|
||||
return { behavior: 'smooth', el: to.hash, top: TOP_WITH_TABS }
|
||||
}
|
||||
if (to.hash) {
|
||||
// We are navigating to an anchor of a new page, add a timeout to let the transition effect finish before scrolling
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve({ el: to.hash, top: 120 })
|
||||
resolve({ el: to.hash, top: TOP_WITH_TABS })
|
||||
}, delay)
|
||||
})
|
||||
}
|
||||
@ -330,9 +328,8 @@ export const router = createRouter({
|
||||
* If a tab navigation exists, an offset to the "top" anchor is added
|
||||
*/
|
||||
return new Promise((resolve, reject) => {
|
||||
const top = to.meta.has_tabs ? TOP_WITH_TABS : TOP_WITHOUT_TABS
|
||||
setTimeout(() => {
|
||||
resolve({ el: '#top', top })
|
||||
resolve({ el: '#top', top: TOP_WITH_TABS })
|
||||
}, delay)
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user