Compare commits

...

18 Commits

  1. 343
      vueHomilyLink/package-lock.json
  2. 2
      vueHomilyLink/package.json
  3. 28
      vueHomilyLink/src/api/ChannelApi.js
  4. 15
      vueHomilyLink/src/api/LiveApi.js
  5. 16
      vueHomilyLink/src/api/index.js
  6. BIN
      vueHomilyLink/src/assets/live.jpg
  7. 36
      vueHomilyLink/src/assets/main.css
  8. 2
      vueHomilyLink/src/components/Nav.vue
  9. 5
      vueHomilyLink/src/main.js
  10. 3
      vueHomilyLink/src/router/index.js
  11. 472
      vueHomilyLink/src/views/ChannelView.vue
  12. 296
      vueHomilyLink/src/views/LiveView.vue
  13. 9
      vueHomilyLink/vite.config.js

343
vueHomilyLink/package-lock.json

@ -8,6 +8,8 @@
"name": "vuehomilylink", "name": "vuehomilylink",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"axios": "^1.7.8",
"element-plus": "^2.9.0",
"pinia": "^2.2.6", "pinia": "^2.2.6",
"vue": "^3.5.12", "vue": "^3.5.12",
"vue-router": "^4.4.5" "vue-router": "^4.4.5"
@ -487,6 +489,24 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@ctrl/tinycolor": {
"version": "3.6.1",
"resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
"integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/@element-plus/icons-vue": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
"integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==",
"license": "MIT",
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.21.5", "version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
@ -878,6 +898,31 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@floating-ui/core": {
"version": "1.6.8",
"resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.8.tgz",
"integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.12",
"resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.12.tgz",
"integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.8",
"resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.8.tgz",
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
"license": "MIT"
},
"node_modules/@jridgewell/gen-mapping": { "node_modules/@jridgewell/gen-mapping": {
"version": "0.3.5", "version": "0.3.5",
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
@ -937,6 +982,17 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@popperjs/core": {
"name": "@sxzz/popperjs-es",
"version": "2.11.7",
"resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
"integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@rollup/pluginutils": { "node_modules/@rollup/pluginutils": {
"version": "5.1.3", "version": "5.1.3",
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz",
@ -1219,6 +1275,27 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/lodash": {
"version": "4.17.13",
"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.13.tgz",
"integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==",
"license": "MIT"
},
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"license": "MIT",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==",
"license": "MIT"
},
"node_modules/@vitejs/plugin-vue": { "node_modules/@vitejs/plugin-vue": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.0.tgz", "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.0.tgz",
@ -1434,6 +1511,117 @@
"integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vueuse/core": {
"version": "9.13.0",
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz",
"integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
"license": "MIT",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.13.0",
"@vueuse/shared": "9.13.0",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/core/node_modules/vue-demi": {
"version": "0.14.10",
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/metadata": {
"version": "9.13.0",
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz",
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "9.13.0",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz",
"integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
"license": "MIT",
"dependencies": {
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared/node_modules/vue-demi": {
"version": "0.14.10",
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/async-validator": {
"version": "4.2.5",
"resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
"license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axios": {
"version": "1.7.8",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.8.tgz",
"integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/birpc": { "node_modules/birpc": {
"version": "0.2.19", "version": "0.2.19",
"resolved": "https://registry.npmmirror.com/birpc/-/birpc-0.2.19.tgz", "resolved": "https://registry.npmmirror.com/birpc/-/birpc-0.2.19.tgz",
@ -1514,6 +1702,18 @@
], ],
"license": "CC-BY-4.0" "license": "CC-BY-4.0"
}, },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/convert-source-map": { "node_modules/convert-source-map": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
@ -1558,6 +1758,12 @@
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/dayjs": {
"version": "1.11.13",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"license": "MIT"
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.7", "version": "4.3.7",
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.7.tgz", "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.7.tgz",
@ -1619,6 +1825,15 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.64", "version": "1.5.64",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.64.tgz", "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.64.tgz",
@ -1626,6 +1841,32 @@
"dev": true, "dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/element-plus": {
"version": "2.9.0",
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.0.tgz",
"integrity": "sha512-ccOFXKsauo2dtokAr4OX7gZsb7TuAoVxA2zGRZo5o2yyDDBLBaZxOoFQPoxITSLcHbBfQuNDGK5Iag5hnyKkZA==",
"license": "MIT",
"dependencies": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.3.1",
"@floating-ui/dom": "^1.0.1",
"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
"@types/lodash": "^4.14.182",
"@types/lodash-es": "^4.17.6",
"@vueuse/core": "^9.1.0",
"async-validator": "^4.2.5",
"dayjs": "^1.11.13",
"escape-html": "^1.0.3",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"lodash-unified": "^1.0.2",
"memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.2.0"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/entities": { "node_modules/entities": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
@ -1697,6 +1938,12 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/estree-walker": { "node_modules/estree-walker": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
@ -1727,6 +1974,40 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1" "url": "https://github.com/sindresorhus/execa?sponsor=1"
} }
}, },
"node_modules/follow-redirects": {
"version": "1.15.9",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz",
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fs-extra": { "node_modules/fs-extra": {
"version": "11.2.0", "version": "11.2.0",
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.2.0.tgz", "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.2.0.tgz",
@ -1964,6 +2245,29 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/lodash-unified": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz",
"integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
"license": "MIT",
"peerDependencies": {
"@types/lodash-es": "*",
"lodash": "*",
"lodash-es": "*"
}
},
"node_modules/lru-cache": { "node_modules/lru-cache": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
@ -1983,6 +2287,12 @@
"@jridgewell/sourcemap-codec": "^1.5.0" "@jridgewell/sourcemap-codec": "^1.5.0"
} }
}, },
"node_modules/memoize-one": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
"license": "MIT"
},
"node_modules/merge-stream": { "node_modules/merge-stream": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
@ -1990,6 +2300,27 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mimic-fn": { "node_modules/mimic-fn": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz", "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz",
@ -2052,6 +2383,12 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/normalize-wheel-es": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
"integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==",
"license": "BSD-3-Clause"
},
"node_modules/npm-run-path": { "node_modules/npm-run-path": {
"version": "5.3.0", "version": "5.3.0",
"resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.3.0.tgz", "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.3.0.tgz",
@ -2239,6 +2576,12 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/rfdc": { "node_modules/rfdc": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz",

2
vueHomilyLink/package.json

@ -9,6 +9,8 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"axios": "^1.7.8",
"element-plus": "^2.9.0",
"pinia": "^2.2.6", "pinia": "^2.2.6",
"vue": "^3.5.12", "vue": "^3.5.12",
"vue-router": "^4.4.5" "vue-router": "^4.4.5"

28
vueHomilyLink/src/api/ChannelApi.js

@ -0,0 +1,28 @@
import service from ".";
const ChannelApi = {
//获取频道列表
getchannels(){
return service.get('/list');
},
//获取shows列表
getShows(Id,UserId,FlagType){
return service.post('/channel',{Id,UserId,FlagType});
},
//订阅状态
subscribe(Id,UserId){
return service.post('/subscription',{Id,UserId})
},
//取消订阅
unSubscribe(Id,UserId){
console.log("_________",Id);
return service.delete('/subscription',{
params:{
Id:Id,
UserId:UserId
}
})
}
}
export default ChannelApi;

15
vueHomilyLink/src/api/LiveApi.js

@ -0,0 +1,15 @@
import service from ".";
const liveApi = {
//获取直播列表
getLiveList() {
return service.get('/live');
},
//预约
addReservation(id,userId){
return service.post('/reservation',{id,userId});
},
//取消预约
cancelReservation(id,userId){
return service.delete('/reservation',{id,userId});
}
}

16
vueHomilyLink/src/api/index.js

@ -0,0 +1,16 @@
import axios from "axios";
const service = axios.create({
// baseURL: 'http://192.168.8.191:8080',
// baseURL: 'http://localhost:8080',
baseURL: '/api',
});
// http://192.168.8.191:8080
//Axios的响应拦截器..
service.interceptors.response.use(resp => {
return resp.data;
}, error => {
return Promise.reject(error);
});
export default service;

BIN
vueHomilyLink/src/assets/live.jpg

After

Width: 310  |  Height: 200  |  Size: 39 KiB

36
vueHomilyLink/src/assets/main.css

@ -1,35 +1,7 @@
@import './base.css';
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
font-weight: normal;
}
a,
.green {
text-decoration: none;
color: hsla(160, 100%, 37%, 1);
transition: 0.4s;
padding: 3px;
}
@media (hover: hover) {
a:hover {
background-color: hsla(160, 100%, 37%, 0.2);
html,body{
margin:0px;
height: 100%;
} }
}
@media (min-width: 1024px) {
body {
display: flex;
place-items: center;
}
#app{ #app{
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
}
height: 100%;
} }

2
vueHomilyLink/src/components/Nav.vue

@ -7,7 +7,7 @@
<div class="container"> <div class="container">
<a href="#">频道</a> <a href="#">频道</a>
<a href="#">俱乐部</a> <a href="#">俱乐部</a>
<a href="#">直播</a>
<a href="/live">直播</a>
</div> </div>
</div> </div>
</template> </template>

5
vueHomilyLink/src/main.js

@ -2,13 +2,18 @@ import './assets/main.css'
import { createApp } from 'vue' import { createApp } from 'vue'
import { createPinia } from 'pinia' import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
const app = createApp(App) const app = createApp(App)
app.use(createPinia()) app.use(createPinia())
app.use(router) app.use(router)
app.use(ElementPlus)
app.mount('#app') app.mount('#app')

3
vueHomilyLink/src/router/index.js

@ -19,7 +19,8 @@ const router = createRouter({
component: ClubView, component: ClubView,
}, },
{ {
path: '/channel',
path: '/channel/:id?',
props: true,
name: 'channel', name: 'channel',
component: ChannelView, component: ChannelView,
}, },

472
vueHomilyLink/src/views/ChannelView.vue

@ -1,10 +1,480 @@
<script setup> <script setup>
import Nav from '@/components/Nav.vue';
import { computed, ref } from 'vue';
import {ElMessage} from 'element-plus';
import router from '@/router';
import ChannelApi from '@/api/ChannelApi';
//
const channelList = ref([]);
//
const currentTab = ref(null);
const flagType = ref(null);
//
//
const channel = ref({
id: 1,
image: "https://d31zlh4on95l9h.cloudfront.net/images/52ea7786d329493ea43791533e17ba66.png",
name: "量价时空四维预测术",
//
subscriptionCount: 60,
backgroundImage: "https://d31zlh4on95l9h.cloudfront.net/images/148gntohb80czrcs8ykqfkq1yhuplalr.jpg",
status:true
});
//1-
function getChannels() {
//api
ChannelApi.getchannels().then((result) =>{
console.log(result.data);
channelList.value = result.data;
console.log("++++",channelList.value);
})
}
getChannels();
function toLink(channelId) {
router.push({ path: '/channel', query: { id: channelId } });
flagType.value = null;
currentTab.value = null;
loadShows(channelId,flagType.value);
console.log("flga",flagType.value);
}
function changeTab(channelId, flagType) {
currentTab.value = flagType;
loadShows(channelId,flagType);
}
// 1
const shows = ref([]);
//
function loadShows(channleId,flagType) {
//showsapi,id,userId
ChannelApi.getShows(channleId,90000000,flagType).then((result)=>{
console.log(result.data)
channel.value = result.data.channel;
shows.value = result.data.shows;
})
}
loadShows(channel.value.id,flagType.value);
//
function submit(channelId) {
console.log("频道id",channelId);
ChannelApi.subscribe(channelId,90000000).then((result)=>{
if(result && result.data.success){
ElMessage.success('订阅成功!');
loadShows(channelId,null);
}else{
ElMessage.console.error('订阅失败!');
}
})
}
//
function unsubmit(channelId){
console.log("取消频道id",channelId);
ChannelApi.unSubscribe(channelId,90000000).then((result) =>{
if(result && result.data.success){
console.log("取消频道id+++++++",channelId);
ElMessage.success('取消订阅成功!');
loadShows(channelId,null);
}
})
}
// function buttonActive(){
// }
// buttonActive();
</script> </script>
<template> <template>
频道
<Nav></Nav>
<ChannelNav></ChannelNav>
<div class="club-nav">
<div class="container">
<button v-for="ch in channelList.list" @click="toLink(ch.id)" class="nav-item">{{ ch.name }}</button>
</div>
</div>
<div class="channel">
<div class="channel-head">
<!-- 1-订阅按钮 -->
<button v-if="channel.status && channel.status == true" class="submited"
@click="unsubmit(channel.id)">取消订阅</button>
<button v-else class="submit" @click="submit(channel.id)">订阅</button>
<!-- 2-背景图片 -->
<img alt="" class="bc-image" :src="channel.backgroundImage" />
<!-- 3-频道主题 -->
<div class="channel-title">
<!-- 频道头像 -->
<img alt="" class="title-image" :src="channel.image" />
<!-- 频道title -->
<div class="title-content">
<h3 :name="channel.name">{{ channel.name }}</h3>
<span :subscriptionCount="channel.subscriptionCount">{{ channel.subscriptionCount }}已订阅</span>
</div>
</div>
</div>
<!-- 频道内容 -->
<div class="channel-content">
<!-- 导航栏 -->
<div class="content-nav">
<button
class="tab"
:class="{ active: currentTab == null }"
@click="changeTab(channel.id,null)">全部</button>
<button
class="tab"
:class="{ active: currentTab == 1 }"
@click="changeTab(channel.id,1)">视频</button>
<button
class="tab"
:class="{ active: currentTab == 2 }"
@click="changeTab(channel.id, 2)">文章</button>
</div>
<component :is="currentTabComponent"></component>
<!-- 内容 -->
<!-- 如果是全部 -->
<div v-if="currentTab == null" class="content-list">
<ul class="list-display">
<!-- 一条 -->
<li v-for="show in shows">
<div class="sub-topic">
<!-- 左边 -->
<div class="sub-left">
<img class="sub-image" :src="show.cover" alt="视频缩略图">
<div v-if="show.flagType == 1" :videoDuration="show.videoDuration" class="video-time">
{{ show.videoDuration }}
</div>
</div>
<!-- 右边 -->
<div class="sub-right">
<!-- title -->
<h3 :name="show.name" class="right-title">{{ show.name }}</h3>
<div class="right-inline">
<!-- 发布的用户名 -->
<div class="right-item">
<img :src="show.user.avatar" class="img1">
<div :username="show.user.username">{{ show.user.username }}</div>
</div>
<!-- 评论 -->
<span :comments="show.comments" class="right-item">{{ show.comments }}评论</span>
<!-- 日期 -->
<div :releaseTime="show.releaseTime" class="right-item"> {{ show.releaseTime }}
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
<div v-if="currentTab == 1" class="content-list">
<ul class="list-display">
<!-- 一条 -->
<li v-for="show in shows">
<div class="sub-topic">
<!-- 左边 -->
<div class="sub-left">
<img class="sub-image" :src="show.cover" alt="视频缩略图">
<div v-if="show.flagType == 1" :videoDuration="show.videoDuration" class="video-time">
{{ show.videoDuration }}
</div>
</div>
<!-- 右边 -->
<div class="sub-right">
<!-- title -->
<h3 :name="show.name" class="right-title">{{ show.name }}</h3>
<div class="right-inline">
<!-- 发布的用户名 -->
<div class="right-item">
<img :src="show.user.avatar" class="img1">
<div :username="show.user.username">{{ show.user.username }}</div>
</div>
<!-- 评论 -->
<span :comments="show.comments" class="right-item">{{ show.comments }}评论</span>
<!-- 日期 -->
<div :releaseTime="show.releaseTime" class="right-item"> {{ show.releaseTime }}
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
<div v-if="currentTab == 2" class="content-list">
<ul class="list-display">
<!-- 一条 -->
<li v-for="show in shows">
<div class="sub-topic">
<!-- 左边 -->
<div class="sub-left">
<img class="sub-image" :src="show.cover" alt="视频缩略图">
<div v-if="show.flagType == 1" :videoDuration="show.videoDuration" class="video-time">
{{ show.videoDuration }}
</div>
</div>
<!-- 右边 -->
<div class="sub-right">
<!-- title -->
<h3 :name="show.name" class="right-title">{{ show.name }}</h3>
<div class="right-inline">
<!-- 发布的用户名 -->
<div class="right-item">
<img :src="show.user.avatar" class="img1">
<div :username="show.user.username">{{ show.user.username }}</div>
</div>
<!-- 评论 -->
<span :comments="show.comments" class="right-item">{{ show.comments }}评论</span>
<!-- 日期 -->
<div :releaseTime="show.releaseTime" class="right-item"> {{ show.releaseTime }}
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</template> </template>
<style scoped> <style scoped>
.club-nav {
height: 100vh;
position: fixed;
left: 30px;
top: 30px;
background-color: #ffffff;
overflow-x: hidden;
padding-top: 20px;
transition: 0.5s;
}
.container {
padding: 0;
margin: 0;
list-style-type: none;
background-color: #ffffff;
}
.nav-item {
border: none;
background-color: #ffffff;
padding: 10px 15px;
width: 250px;
height: 60px;
text-decoration: none;
font-size: 18px;
color: rgb(19, 18, 18);
display: block;
transition: 0.3s;
}
.nav-item:hover {
background-color: #407fdf;
color: #f1f1f1;
}
.nav-item.router-link-active {
background-color: #407fdf;
color: white;
border-radius: 5%;
}
.channel {
width: 800px;
margin-left: auto;
margin-right: auto;
}
.channel-head {
position: relative;
height: 200px;
width: 100%;
}
.bc-image {
height: 100%;
width: 100%;
}
.submited {
position: absolute;
/* 绝对定位 */
top: 50px;
/* 根据需要调整位置 */
right: 10px;
/* 根据需要调整位置 */
color: rgb(129, 132, 134);
background-color: aliceblue;
padding: 10px;
border-radius: 10%;
z-index: 999;
}
.submit {
position: absolute;
/* 绝对定位 */
top: 50px;
/* 根据需要调整位置 */
right: 10px;
/* 根据需要调整位置 */
color: rgb(129, 132, 134);
background-color: aliceblue;
padding: 10px 20px;
border-radius: 10%;
z-index: 999;
}
.channel-title {
position: absolute;
top: 0px;
left: 0px;
padding-top: 60px;
padding-left: 50px;
box-sizing: border-box;
background: rgba(0, 0, 0, 0.4);
width: 100%;
height: 100%;
overflow: hidden;
}
.title-image {
width: 90px;
height: 90px;
margin-right: 25px;
vertical-align: top;
border-radius: 50%;
}
.title-content {
display: inline-block;
position: absolute;
width: 400px;
color: white;
overflow: hidden;
}
.channel-title h3 {
max-width: 75%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 24px;
color: #fff;
margin: 0px;
z-index: 999;
}
.channel-title span {
padding: 4px 0;
font-size: 14px;
color: #fff;
}
.content-nav {
display: flex;
justify-content: flex-start;
/* 修正了属性名中的空格 */
background-color: #fff;
/* 修正了属性名中的空格 */
border-bottom: 1px solid #ccc;
/* 修正了属性名中的空格 */
margin: 10px;
}
.tab {
padding: 10px 20px;
border: none;
background-color: transparent;
/* 修正了属性名中的空格 */
cursor: pointer;
font-size: 16px;
}
.active {
color: red;
border-bottom: 2px solid red;
}
.list-display {
list-style-type: none;
padding: 0px;
}
.sub-topic {
margin: 10px 0;
padding: 10px;
display: flex;
}
.sub-left {
height: 112px;
width: 200px;
position: relative;
.sub-image {
width: 100%;
height: 100%;
}
.video-time {
position: absolute;
left: 70%;
top: 80%;
color: #fff;
background-color: rgba(31, 30, 30, 0.5);
border-radius: 20%;
font-size: smaller;
}
}
.right-inline {
display: flex;
margin-bottom: 15px;
align-items: center;
font-size: 16px;
}
.right-title {
margin-left: 10px;
}
.right-item {
display: flex;
color: #8e8e8e;
font-size: 14px;
margin-right: 18px;
align-items: center;
}
.img1 {
margin-left: 10px;
width: 22px;
height: 22px;
border-radius: 50%;
}
</style> </style>

296
vueHomilyLink/src/views/LiveView.vue

@ -1,10 +1,300 @@
<template>
<!-- 卡片 -->
<div class="card-container">
<div v-for="(live, index) in liveList" :key="index" class="card">
<div class="cover-image" :class="{ 'no-overlay': !live.status == 1 }" style="position:relative;">
<img :src=live.cover alt="节目1">
<div v-if="live.status == 1" class="overlay">即将开播</div>
<div v-if="live.status == 1" class="start-time">{{ getDateDay(live.startTime) }} {{ live.startTime.slice(11, 16) }}开播</div>
</div>
<div class="card-content">
<div class="card-title">{{ live.liveName }}</div>
<div class="card-actions">
<!-- 用户头像 -->
<img :src=live.user.avatar alt="节目1" class="user-avatar">
<!-- 用户昵称与头像同行显示 -->
<div class="card-info">{{ live.user.userName }}</div>
<!-- 预约按钮,如果预约过了按钮变灰色文字变灰色按钮文字为已预约 -->
<a v-if="live.reservation == 0" href="#" class="card-button"
@click="booking(live.id, live.user.userId)">预约</a>
<a v-else href="#" class="card-button" style="background-color: #ccc;">已预约</a>
</div>
</div>
</div>
</div>
</template>
<script setup> <script setup>
import { ref } from 'vue';
/*
模拟后端数据
*/
const liveList = ref([]);
//
function getLive() {
liveList.value = [
{
id: 1,
cover: "src/assets/live.jpg",
user: {
userId: 1,
userName: "冷辉老师",
avatar: "src/assets/live.jpg"
},
liveName: "猎庄之顶级波段",
startTime: "2024-12-01 09:55",
reservation: 1, //01
status: 1 //01
},
{
id: 2,
cover: "src/assets/live.jpg",
user: {
userId: 2,
userName: "冷辉老师",
avatar: "src/assets/live.jpg"
},
liveName: "猎庄之顶级波段",
startTime: "2024-12-01 09:55",
reservation: 1, //01
status: 1
},
{
id: 3,
cover: "src/assets/live.jpg",
user: {
userId: 3,
userName: "冷辉老师",
avatar: "src/assets/live.jpg"
},
liveName: "猎庄之顶级波段",
startTime: "2024-11-30 12:55",
reservation: 1, //01
status: 1
},
{
id: 4,
cover: "src/assets/live.jpg",
user: {
userId: 4,
userName: "冷辉老师",
avatar: "src/assets/live.jpg"
},
liveName: "猎庄之顶级波段",
startTime: "2024-12-30 12:55",
reservation: 0, //01
status: 1
},
{
id: 5,
cover: "src/assets/live.jpg",
user: {
userId: 5,
userName: "冷辉老师",
avatar: "src/assets/live.jpg"
},
liveName: "猎庄之顶级波段",
startTime: "2024-12-30 12:55",
reservation: 0, //01
status: 1,
}
]
}
getLive();
//
function getDateDay(startTime) {
const now = new Date();
const start = new Date(startTime);
const oneDay = 24 * 60 * 60 * 1000; //
if (now.toDateString() == start.toDateString()) {
return "今天";
} else if (now.getTime() + oneDay >= start.getTime()) {
return "明天";
} else {
return startTime.slice(5, 10);
}
}
// //
// const userInfo = ref([]);
// function getUserInfo() {
// userInfo.value = {
// userId: 1,
// userName: "",
// avatar: "src/assets/live.jpg",
// //
// reservationList: [1,2,3]
// }
// }
// getUserInfo();
// console.log(userInfo.value);
// /* */
// function isBooking(liveId) {
// for (let i = 0; i < userInfo.value.reservationList.length; i++) {
// if (userInfo.value.reservationList[i] == liveId) {
// return true;
// }
// }
// return false;
// }
/*点击预约按钮以后显示预约成功的提示,并将按钮变为不可点击状态,且将按钮的文字改为“已预约”,并将按钮的背景颜色改为灰色*/
function booking(liveId, userId) {
alert("预约成功!");
}
</script> </script>
<template>
直播
</template>
<style scoped> <style scoped>
.card-container {
/*居中显示*/
margin-left: auto;
margin-right: auto;
/*宽度*/
width: 916px;
font-family: Arial, sans-serif;
padding: 0;
flex-wrap: wrap;
/*超出自动换行*/
background-color: #f4f4f4;
display: flex;
align-items: center;
}
.card {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
margin: 10px;
overflow: hidden;
border: #666;
height: 190px;
width: 209px;
}
.card .cover-image img {
width: 100%;
height: 100%;
/*图片占满整个卡片*/
object-fit: cover;
border-radius: 8px;
}
.cover-image {
position: relative;
height: 120px;
width: 208px;
border-radius: 8px;
}
/*即将开播图层*/
.overlay {
position: absolute;
z-index: 2;
text-align: center;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 18px;
}
/*开播时间*/
.start-time {
position: absolute;
z-index: 2;
text-align: center;
top: 60%;
left: 50%;
transform: translate(-50%, -50%);
color: #ffffffaf;
font-size: 15px;
width: 120px;
}
.cover-image::before {
content: " ";
position: absolute;
top: 0;
left: 0;
width: 207px;
height: 120px;
/*最后一个参数是半透明度,可以透过调整0-1的数值,调整到满意的透明度*/
background-color: rgba(0, 0, 0, 0.3);
border-radius: 8px;
}
/*用于隐藏样式*/
.cover-image.no-overlay::before {
display: none;
}
.card-content {
padding: 8px;
}
.card-title {
font-size: 13px;
font-weight: bold;
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-info {
font-size: 14px;
color: #666;
}
.card-button {
display: inline-block;
padding: 5px 5px;
background-color: #eb8b31;
color: #fff;
text-decoration: none;
border-radius: 20px;
font-size: small;
width: 50px;
text-align: center;
margin-left: auto;
}
.card-actions {
display: flex;
align-items: center;
/* 垂直居中对齐 */
justify-content: space-between;
/* 按钮右对齐 */
}
.user-avatar {
border-radius: 50%;
width: 20px;
height: 20px;
}
.card-info {
margin-left: 5px;
/* 昵称与头像之间的间距 */
margin-top: 0;
/* 移除顶部外边距 */
/*超长以后将内容省略显示*/
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 90px;
font-size: 12px;
}
</style> </style>

9
vueHomilyLink/vite.config.js

@ -15,4 +15,13 @@ export default defineConfig({
'@': fileURLToPath(new URL('./src', import.meta.url)) '@': fileURLToPath(new URL('./src', import.meta.url))
}, },
}, },
server: {
proxy: {
'/api': {
target: 'http://192.168.9.19:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}) })
Loading…
Cancel
Save