Add unocss eslint config and apply changes.

This commit is contained in:
Kavin 2023-08-13 18:31:57 +01:00
parent da9d71d6c8
commit a153f87e58
No known key found for this signature in database
GPG Key ID: 6E4598CA5C92C41F
32 changed files with 251 additions and 107 deletions

View File

@ -3,5 +3,5 @@ module.exports = {
env: { env: {
node: true, node: true,
}, },
extends: ["plugin:vue/vue3-recommended", "eslint:recommended", "plugin:prettier/recommended"], extends: ["plugin:vue/vue3-recommended", "eslint:recommended", "@unocss", "plugin:prettier/recommended"],
}; };

View File

@ -33,6 +33,7 @@
"@iconify-json/fa6-brands": "1.1.13", "@iconify-json/fa6-brands": "1.1.13",
"@iconify-json/fa6-solid": "1.1.15", "@iconify-json/fa6-solid": "1.1.15",
"@intlify/unplugin-vue-i18n": "0.12.2", "@intlify/unplugin-vue-i18n": "0.12.2",
"@unocss/eslint-config": "0.55.0",
"@unocss/preset-icons": "0.55.0", "@unocss/preset-icons": "0.55.0",
"@unocss/preset-uno": "0.55.0", "@unocss/preset-uno": "0.55.0",
"@unocss/preset-web-fonts": "0.55.0", "@unocss/preset-web-fonts": "0.55.0",

View File

@ -70,6 +70,9 @@ devDependencies:
'@intlify/unplugin-vue-i18n': '@intlify/unplugin-vue-i18n':
specifier: 0.12.2 specifier: 0.12.2
version: 0.12.2(rollup@2.79.1)(vue-i18n@9.2.2) version: 0.12.2(rollup@2.79.1)(vue-i18n@9.2.2)
'@unocss/eslint-config':
specifier: 0.55.0
version: 0.55.0(eslint@8.47.0)(typescript@5.1.6)
'@unocss/preset-icons': '@unocss/preset-icons':
specifier: 0.55.0 specifier: 0.55.0
version: 0.55.0 version: 0.55.0
@ -1953,10 +1956,75 @@ packages:
'@types/node': 20.4.8 '@types/node': 20.4.8
dev: true dev: true
/@types/semver@7.5.0:
resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
dev: true
/@types/trusted-types@2.0.3: /@types/trusted-types@2.0.3:
resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==} resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==}
dev: true dev: true
/@typescript-eslint/scope-manager@6.3.0:
resolution: {integrity: sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
'@typescript-eslint/types': 6.3.0
'@typescript-eslint/visitor-keys': 6.3.0
dev: true
/@typescript-eslint/types@6.3.0:
resolution: {integrity: sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg==}
engines: {node: ^16.0.0 || >=18.0.0}
dev: true
/@typescript-eslint/typescript-estree@6.3.0(typescript@5.1.6):
resolution: {integrity: sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 6.3.0
'@typescript-eslint/visitor-keys': 6.3.0
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
semver: 7.5.4
ts-api-utils: 1.0.1(typescript@5.1.6)
typescript: 5.1.6
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/utils@6.3.0(eslint@8.47.0)(typescript@5.1.6):
resolution: {integrity: sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==}
engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0)
'@types/json-schema': 7.0.12
'@types/semver': 7.5.0
'@typescript-eslint/scope-manager': 6.3.0
'@typescript-eslint/types': 6.3.0
'@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6)
eslint: 8.47.0
semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/@typescript-eslint/visitor-keys@6.3.0:
resolution: {integrity: sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw==}
engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
'@typescript-eslint/types': 6.3.0
eslint-visitor-keys: 3.4.3
dev: true
/@unocss/astro@0.55.0(rollup@2.79.1)(vite@4.4.9): /@unocss/astro@0.55.0(rollup@2.79.1)(vite@4.4.9):
resolution: {integrity: sha512-Qqk8zONPBBigEcUOGhEwBPIQmWnQGpjpQrSdpjs86BphKbQcqWHES1fQA83Fk2tpZ08zo0zAPDJ8VhfR+c+yqg==} resolution: {integrity: sha512-Qqk8zONPBBigEcUOGhEwBPIQmWnQGpjpQrSdpjs86BphKbQcqWHES1fQA83Fk2tpZ08zo0zAPDJ8VhfR+c+yqg==}
peerDependencies: peerDependencies:
@ -2007,6 +2075,32 @@ packages:
resolution: {integrity: sha512-TcTugpuhsv6OwMsP3iFIG8FVc9N5JzkojIGNAKF8I2WBftZ//3QcpEHiHc1mH3MlPYfJgUvCcT6/Gad55qmHzg==} resolution: {integrity: sha512-TcTugpuhsv6OwMsP3iFIG8FVc9N5JzkojIGNAKF8I2WBftZ//3QcpEHiHc1mH3MlPYfJgUvCcT6/Gad55qmHzg==}
dev: true dev: true
/@unocss/eslint-config@0.55.0(eslint@8.47.0)(typescript@5.1.6):
resolution: {integrity: sha512-18kDqTFQuATIOh+rja920q/S4I0aLLVG1ccZ1i8cJmpNF+XGuevu7UtPjxlcNq1F7pzmTlq/79jYrjBDZBGL/g==}
engines: {node: '>=14'}
dependencies:
'@unocss/eslint-plugin': 0.55.0(eslint@8.47.0)(typescript@5.1.6)
transitivePeerDependencies:
- eslint
- supports-color
- typescript
dev: true
/@unocss/eslint-plugin@0.55.0(eslint@8.47.0)(typescript@5.1.6):
resolution: {integrity: sha512-w6VjKtjTtiuG7jIZXUZzSCHgarV2bp5dMH3ALOhhvNZYfqLbcrJPSPk0RisVZ+uF87QCK4WSlKdXmO4UBd0ENg==}
engines: {node: '>=14'}
dependencies:
'@typescript-eslint/utils': 6.3.0(eslint@8.47.0)(typescript@5.1.6)
'@unocss/config': 0.55.0
'@unocss/core': 0.55.0
magic-string: 0.30.2
synckit: 0.8.5
transitivePeerDependencies:
- eslint
- supports-color
- typescript
dev: true
/@unocss/extractor-arbitrary-variants@0.55.0: /@unocss/extractor-arbitrary-variants@0.55.0:
resolution: {integrity: sha512-FCel+gJ3N8C/361yQ3gYTmbCjX3DXQ+LdxBiAawapbtTA4eXw55/f7cpiiWcHoouCRrWIEMOQN5DskAJvmMaTw==} resolution: {integrity: sha512-FCel+gJ3N8C/361yQ3gYTmbCjX3DXQ+LdxBiAawapbtTA4eXw55/f7cpiiWcHoouCRrWIEMOQN5DskAJvmMaTw==}
dependencies: dependencies:
@ -2340,6 +2434,11 @@ packages:
is-array-buffer: 3.0.2 is-array-buffer: 3.0.2
dev: true dev: true
/array-union@2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
dev: true
/arraybuffer.prototype.slice@1.0.1: /arraybuffer.prototype.slice@1.0.1:
resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==} resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2713,6 +2812,13 @@ packages:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
dev: false dev: false
/dir-glob@3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
dependencies:
path-type: 4.0.0
dev: true
/doctrine@3.0.0: /doctrine@3.0.0:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
@ -3299,6 +3405,18 @@ packages:
define-properties: 1.2.0 define-properties: 1.2.0
dev: true dev: true
/globby@11.1.0:
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
dependencies:
array-union: 2.1.0
dir-glob: 3.0.1
fast-glob: 3.3.1
ignore: 5.2.4
merge2: 1.4.1
slash: 3.0.0
dev: true
/gopd@1.0.1: /gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
dependencies: dependencies:
@ -4140,6 +4258,11 @@ packages:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true dev: true
/path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
dev: true
/pathe@1.1.1: /pathe@1.1.1:
resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
dev: true dev: true
@ -4482,6 +4605,11 @@ packages:
totalist: 3.0.1 totalist: 3.0.1
dev: true dev: true
/slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
dev: true
/source-map-js@1.0.2: /source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -4692,6 +4820,15 @@ packages:
punycode: 2.3.0 punycode: 2.3.0
dev: true dev: true
/ts-api-utils@1.0.1(typescript@5.1.6):
resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==}
engines: {node: '>=16.13.0'}
peerDependencies:
typescript: '>=4.2.0'
dependencies:
typescript: 5.1.6
dev: true
/tslib@2.6.1: /tslib@2.6.1:
resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
dev: true dev: true
@ -4751,6 +4888,12 @@ packages:
is-typed-array: 1.1.12 is-typed-array: 1.1.12
dev: true dev: true
/typescript@5.1.6:
resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
/ufo@1.2.0: /ufo@1.2.0:
resolution: {integrity: sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==} resolution: {integrity: sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==}
dev: true dev: true

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="flex flex-col w-full min-h-screen px-1vw py-5 antialiased reset" :class="[theme]"> <div class="reset min-h-screen w-full flex flex-col px-1vw py-5 antialiased" :class="[theme]">
<div class="flex-1"> <div class="flex-1">
<NavBar /> <NavBar />
<router-view v-slot="{ Component }"> <router-view v-slot="{ Component }">

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="flex flex-col flex-justify-between"> <div class="flex flex-col flex-justify-between">
<router-link :to="props.item.url"> <router-link :to="props.item.url">
<div class="flex justify-center my-4"> <div class="my-4 flex justify-center">
<img class="aspect-square rounded-full w-[50%]" :src="props.item.thumbnail" loading="lazy" /> <img class="aspect-square w-[50%] rounded-full" :src="props.item.thumbnail" loading="lazy" />
</div> </div>
<p> <p>
<span v-text="props.item.name" /> <span v-text="props.item.name" />

View File

@ -5,13 +5,13 @@
<img <img
v-if="channel.bannerUrl" v-if="channel.bannerUrl"
:src="channel.bannerUrl" :src="channel.bannerUrl"
class="w-full py-1.5 h-30 md:h-50 object-cover" class="h-30 w-full object-cover py-1.5 md:h-50"
loading="lazy" loading="lazy"
/> />
<div class="flex flex-col md:flex-row justify-between items-center"> <div class="flex flex-col items-center justify-between md:flex-row">
<div class="flex place-items-center"> <div class="flex place-items-center">
<img height="48" width="48" class="rounded-full m-1" :src="channel.avatarUrl" /> <img height="48" width="48" class="m-1 rounded-full" :src="channel.avatarUrl" />
<div class="flex gap-1 items-center"> <div class="flex items-center gap-1">
<h1 class="!text-xl" v-text="channel.name" /> <h1 class="!text-xl" v-text="channel.name" />
<font-awesome-icon v-if="channel.verified" class="!text-xl" icon="check" /> <font-awesome-icon v-if="channel.verified" class="!text-xl" icon="check" />
</div> </div>
@ -46,7 +46,7 @@
<WatchOnButton :link="`https://youtube.com/channel/${channel.id}`" /> <WatchOnButton :link="`https://youtube.com/channel/${channel.id}`" />
<div class="flex my-2 mx-1"> <div class="mx-1 my-2 flex">
<button <button
v-for="(tab, index) in tabs" v-for="(tab, index) in tabs"
:key="tab.name" :key="tab.name"

View File

@ -1,6 +1,6 @@
<template> <template>
<!-- desktop view --> <!-- desktop view -->
<div v-if="!mobileLayout" class="flex-col overflow-y-scroll max-w-35vw max-h-75vh min-h-64 lt-lg:hidden"> <div v-if="!mobileLayout" class="max-h-75vh max-w-35vw min-h-64 flex-col overflow-y-scroll lt-lg:hidden">
<h2 class="mb-2 bg-gray-500/50 p-2" aria-label="chapters" title="chapters"> <h2 class="mb-2 bg-gray-500/50 p-2" aria-label="chapters" title="chapters">
{{ $t("video.chapters") }} ({{ chapters.length }}) {{ $t("video.chapters") }} ({{ chapters.length }})
</h2> </h2>
@ -12,9 +12,9 @@
@click="$emit('seek', chapter.start)" @click="$emit('seek', chapter.start)"
> >
<div class="flex"> <div class="flex">
<span class="mt-5 mr-2 text-current" v-text="index + 1" /> <span class="mr-2 mt-5 text-current" v-text="index + 1" />
<img class="shrink-0" :src="chapter.image" :alt="chapter.title" /> <img class="shrink-0" :src="chapter.image" :alt="chapter.title" />
<div class="flex flex-col m-2"> <div class="m-2 flex flex-col">
<span class="text-sm" :title="chapter.title" v-text="chapter.title" /> <span class="text-sm" :title="chapter.title" v-text="chapter.title" />
<span class="text-sm font-bold text-blue-500" v-text="timeFormat(chapter.start)" /> <span class="text-sm font-bold text-blue-500" v-text="timeFormat(chapter.start)" />
</div> </div>
@ -25,7 +25,7 @@
<!-- mobile vertical view --> <!-- mobile vertical view -->
<div <div
v-if="mobileLayout && getPreferenceString('mobileChapterLayout') == 'Vertical'" v-if="mobileLayout && getPreferenceString('mobileChapterLayout') == 'Vertical'"
class="flex flex-col overflow-y-scroll max-h-64" class="max-h-64 flex flex-col overflow-y-scroll"
> >
<h2 class="mb-2 bg-gray-500/50 p-2" aria-label="chapters" title="chapters"> <h2 class="mb-2 bg-gray-500/50 p-2" aria-label="chapters" title="chapters">
{{ $t("video.chapters") }} ({{ chapters.length }}) {{ $t("video.chapters") }} ({{ chapters.length }})
@ -38,9 +38,9 @@
@click="$emit('seek', chapter.start)" @click="$emit('seek', chapter.start)"
> >
<div class="flex"> <div class="flex">
<span class="mt-5 mr-2 text-current" v-text="index + 1" /> <span class="mr-2 mt-5 text-current" v-text="index + 1" />
<img class="shrink-0" :src="chapter.image" :alt="chapter.title" /> <img class="shrink-0" :src="chapter.image" :alt="chapter.title" />
<div class="flex flex-col m-2"> <div class="m-2 flex flex-col">
<span class="text-sm" :title="chapter.title" v-text="chapter.title" /> <span class="text-sm" :title="chapter.title" v-text="chapter.title" />
<span class="text-sm font-bold text-blue-500" v-text="timeFormat(chapter.start)" /> <span class="text-sm font-bold text-blue-500" v-text="timeFormat(chapter.start)" />
</div> </div>

View File

@ -1,5 +1,5 @@
<template v-if="text"> <template v-if="text">
<div class="whitespace-pre-wrap py-2 mx-1"> <div class="mx-1 whitespace-pre-wrap py-2">
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<span v-if="showFullText" v-html="fullText()" /> <span v-if="showFullText" v-html="fullText()" />
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
@ -7,7 +7,7 @@
<span v-if="text.length > 100 && !showFullText">...</span> <span v-if="text.length > 100 && !showFullText">...</span>
<button <button
v-if="text.length > 100" v-if="text.length > 100"
class="hover:underline font-semibold text-neutral-500 block whitespace-normal" class="block whitespace-normal font-semibold text-neutral-500 hover:underline"
@click="showFullText = !showFullText" @click="showFullText = !showFullText"
> >
[{{ showFullText ? $t("actions.show_less") : $t("actions.show_more") }}] [{{ showFullText ? $t("actions.show_less") : $t("actions.show_more") }}]

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="comment flex mt-1.5"> <div class="comment mt-1.5 flex">
<img <img
:src="comment.thumbnail" :src="comment.thumbnail"
class="comment-avatar rounded-full w-12 h-12" class="comment-avatar h-12 w-12 rounded-full"
height="48" height="48"
width="48" width="48"
loading="lazy" loading="lazy"
@ -23,10 +23,10 @@
</div> </div>
<div class="comment-author"> <div class="comment-author">
<router-link class="font-bold link" :to="comment.commentorUrl">{{ comment.author }}</router-link> <router-link class="link font-bold" :to="comment.commentorUrl">{{ comment.author }}</router-link>
<font-awesome-icon v-if="comment.verified" class="ml-1.5" icon="check" /> <font-awesome-icon v-if="comment.verified" class="ml-1.5" icon="check" />
</div> </div>
<div class="comment-meta text-sm mb-1.5" v-text="comment.commentedTime" /> <div class="comment-meta mb-1.5 text-sm" v-text="comment.commentedTime" />
</div> </div>
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<div class="whitespace-pre-wrap" v-html="purifiedText" /> <div class="whitespace-pre-wrap" v-html="purifiedText" />

View File

@ -2,7 +2,7 @@
<ModalComponent @close="$emit('close')"> <ModalComponent @close="$emit('close')">
<div> <div>
<h3 class="text-xl" v-text="message" /> <h3 class="text-xl" v-text="message" />
<div class="ml-auto mt-8 flex gap-2 w-min"> <div class="ml-auto mt-8 w-min flex gap-2">
<button v-t="'actions.cancel'" class="btn" @click="$emit('close')" /> <button v-t="'actions.cancel'" class="btn" @click="$emit('close')" />
<button v-t="'actions.okay'" class="btn" @click="$emit('confirm')" /> <button v-t="'actions.okay'" class="btn" @click="$emit('confirm')" />
</div> </div>

View File

@ -1,7 +1,7 @@
<template> <template>
<h1 v-t="'titles.feed'" class="font-bold text-center my-4" /> <h1 v-t="'titles.feed'" class="my-4 text-center font-bold" />
<div class="flex flex-wrap md:items-center flex-col md:flex-row gap-2 children:(flex gap-1 items-center)"> <div class="flex flex-col flex-wrap gap-2 children:(flex items-center gap-1) md:flex-row md:items-center">
<span> <span>
<label for="filters"> <label for="filters">
<strong v-text="`${$t('actions.filter')}:`" /> <strong v-text="`${$t('actions.filter')}:`" />

View File

@ -1,5 +1,5 @@
<template> <template>
<footer class="text-center py-4 rounded-xl children:(mx-3) w-full mt-10"> <footer class="mt-10 w-full rounded-xl py-4 text-center children:(mx-3)">
<a aria-label="GitHub" href="https://github.com/TeamPiped/Piped" target="_blank"> <a aria-label="GitHub" href="https://github.com/TeamPiped/Piped" target="_blank">
<font-awesome-icon :icon="['fab', 'github']" /> <font-awesome-icon :icon="['fab', 'github']" />
<span v-t="'actions.source_code'" class="ml-2" /> <span v-t="'actions.source_code'" class="ml-2" />

View File

@ -1,21 +1,21 @@
<template> <template>
<h1 v-t="'titles.history'" class="font-bold text-center mb-3" /> <h1 v-t="'titles.history'" class="mb-3 text-center font-bold" />
<div class="flex"> <div class="flex">
<div class="flex md:items-center gap-2 flex-col md:flex-row"> <div class="flex flex-col gap-2 md:flex-row md:items-center">
<button v-t="'actions.clear_history'" class="btn" @click="clearHistory" /> <button v-t="'actions.clear_history'" class="btn" @click="clearHistory" />
<button v-t="'actions.export_to_json'" class="btn" @click="exportHistory" /> <button v-t="'actions.export_to_json'" class="btn" @click="exportHistory" />
<div class="ml-auto flex gap-1 items-center"> <div class="ml-auto flex items-center gap-1">
<SortingSelector by-key="watchedAt" @apply="order => videos.sort(order)" /> <SortingSelector by-key="watchedAt" @apply="order => videos.sort(order)" />
</div> </div>
</div> </div>
<div class="flex ml-4 items-center"> <div class="ml-4 flex items-center">
<input id="autoDelete" v-model="autoDeleteHistory" type="checkbox" @change="onChange" /> <input id="autoDelete" v-model="autoDeleteHistory" type="checkbox" @change="onChange" />
<label v-t="'actions.delete_automatically'" class="ml-2" for="autoDelete" /> <label v-t="'actions.delete_automatically'" class="ml-2" for="autoDelete" />
<select v-model="autoDeleteDelayHours" class="pl-3 ml-3 select" @change="onChange"> <select v-model="autoDeleteDelayHours" class="select ml-3 pl-3" @change="onChange">
<option v-t="{ path: 'info.hours', args: { amount: '1' } }" value="1" /> <option v-t="{ path: 'info.hours', args: { amount: '1' } }" value="1" />
<option v-t="{ path: 'info.hours', args: { amount: '3' } }" value="3" /> <option v-t="{ path: 'info.hours', args: { amount: '3' } }" value="3" />
<option v-t="{ path: 'info.hours', args: { amount: '6' } }" value="6" /> <option v-t="{ path: 'info.hours', args: { amount: '6' } }" value="6" />

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-if="!showContent" class="flex min-h-[75vh] w-full justify-center items-center"> <div v-if="!showContent" class="min-h-[75vh] w-full flex items-center justify-center">
<span id="spinner" /> <span id="spinner" />
</div> </div>
<div v-else> <div v-else>

View File

@ -1,5 +1,5 @@
<template> <template>
<h1 v-t="'titles.login'" class="font-bold text-center my-4" /> <h1 v-t="'titles.login'" class="my-4 text-center font-bold" />
<hr /> <hr />
<div class="text-center"> <div class="text-center">
<form class="children:pb-3"> <form class="children:pb-3">

View File

@ -1,21 +1,21 @@
<template> <template>
<nav class="flex flex-wrap items-center justify-center px-2 sm:px-4 pb-2.5 w-full relative"> <nav class="relative w-full flex flex-wrap items-center justify-center px-2 pb-2.5 sm:px-4">
<div class="flex-1 flex justify-start"> <div class="flex flex-1 justify-start">
<router-link class="flex font-bold text-3xl items-center font-sans" :to="homePagePath" <router-link class="flex items-center text-3xl font-bold font-sans" :to="homePagePath"
><img ><img
alt="logo" alt="logo"
src="/img/icons/logo.svg" src="/img/icons/logo.svg"
height="32" height="32"
width="32" width="32"
class="w-10 mr-[-0.6rem]" class="mr-[-0.6rem] w-10"
/>iped</router-link />iped</router-link
> >
</div> </div>
<div class="lt-md:hidden search-container"> <div class="search-container lt-md:hidden">
<input <input
ref="videoSearch" ref="videoSearch"
v-model="searchText" v-model="searchText"
class="input w-72 h-10 pr-20" class="input h-10 w-72 pr-20"
type="text" type="text"
role="search" role="search"
:title="$t('actions.search')" :title="$t('actions.search')"
@ -31,13 +31,13 @@
<div class="i-fa6-solid:magnifying-glass"></div> <div class="i-fa6-solid:magnifying-glass"></div>
</button> </button>
<!-- three vertical lines for toggling the hamburger menu on mobile --> <!-- three vertical lines for toggling the hamburger menu on mobile -->
<button class="md:hidden flex flex-col justify-end mr-3" @click="showTopNav = !showTopNav"> <button class="mr-3 flex flex-col justify-end md:hidden" @click="showTopNav = !showTopNav">
<span class="line"></span> <span class="line"></span>
<span class="line"></span> <span class="line"></span>
<span class="line"></span> <span class="line"></span>
</button> </button>
<!-- navigation bar for large screen devices --> <!-- navigation bar for large screen devices -->
<ul class="hidden md:(flex-1 flex justify-end flex text-1xl children:pl-3)"> <ul class="md:text-1xl hidden md:(flex flex flex-1 justify-end children:pl-3)">
<li v-if="shouldShowTrending"> <li v-if="shouldShowTrending">
<router-link v-t="'titles.trending'" to="/trending" /> <router-link v-t="'titles.trending'" to="/trending" />
</li> </li>
@ -64,7 +64,7 @@
<!-- navigation bar for mobile devices --> <!-- navigation bar for mobile devices -->
<div <div
v-if="showTopNav" v-if="showTopNav"
class="mobile-nav flex flex-col mb-4 children:(p-1 w-full border-b border-dark-100 flex items-center gap-1)" class="mobile-nav mb-4 flex flex-col children:(w-full flex items-center gap-1 border-b border-dark-100 p-1)"
> >
<router-link v-if="shouldShowTrending" to="/trending"> <router-link v-if="shouldShowTrending" to="/trending">
<div class="i-fa6-solid:fire"></div> <div class="i-fa6-solid:fire"></div>
@ -96,7 +96,7 @@
</router-link> </router-link>
</div> </div>
<!-- search suggestions for mobile devices --> <!-- search suggestions for mobile devices -->
<div class="w-full mb-2 md:hidden search-container"> <div class="search-container mb-2 w-full md:hidden">
<input <input
v-model="searchText" v-model="searchText"
class="input h-10 w-full" class="input h-10 w-full"

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="flex flex-col justify-center items-center min-h-[88vh]"> <div class="min-h-[88vh] flex flex-col items-center justify-center">
<h1 class="font-bold !text-9xl">404</h1> <h1 class="font-bold !text-9xl">404</h1>
<h2 v-t="'info.page_not_found'" class="!text-2xl" /> <h2 v-t="'info.page_not_found'" class="!text-2xl" />
<a v-t="'actions.back_to_home'" class="btn mt-16" href="/" /> <a v-t="'actions.back_to_home'" class="btn mt-16" href="/" />

View File

@ -1,10 +1,10 @@
<template> <template>
<ModalComponent> <ModalComponent>
<span v-t="'actions.select_playlist'" class="text-2xl w-max inline-block" /> <span v-t="'actions.select_playlist'" class="inline-block w-max text-2xl" />
<select v-model="selectedPlaylist" class="select w-full mt-3"> <select v-model="selectedPlaylist" class="select mt-3 w-full">
<option v-for="playlist in playlists" :key="playlist.id" :value="playlist.id" v-text="playlist.name" /> <option v-for="playlist in playlists" :key="playlist.id" :value="playlist.id" v-text="playlist.name" />
</select> </select>
<div class="flex justify-between w-full mt-3"> <div class="mt-3 w-full flex justify-between">
<button ref="addButton" v-t="'actions.create_playlist'" class="btn" @click="onCreatePlaylist" /> <button ref="addButton" v-t="'actions.create_playlist'" class="btn" @click="onCreatePlaylist" />
<button <button
ref="addButton" ref="addButton"

View File

@ -2,11 +2,11 @@
<ErrorHandler v-if="playlist && playlist.error" :message="playlist.message" :error="playlist.error" /> <ErrorHandler v-if="playlist && playlist.error" :message="playlist.message" :error="playlist.error" />
<LoadingIndicatorPage v-show="!playlist?.error" :show-content="playlist"> <LoadingIndicatorPage v-show="!playlist?.error" :show-content="playlist">
<h1 class="ml-1 mb-1 mt-4 text-3xl!" v-text="playlist.name" /> <h1 class="mb-1 ml-1 mt-4 text-3xl!" v-text="playlist.name" />
<CollapsableText v-if="playlist?.description" :text="playlist.description" /> <CollapsableText v-if="playlist?.description" :text="playlist.description" />
<div class="flex justify-between items-center mt-1"> <div class="mt-1 flex items-center justify-between">
<div> <div>
<router-link class="link flex items-center gap-3" :to="playlist.uploaderUrl || '/'"> <router-link class="link flex items-center gap-3" :to="playlist.uploaderUrl || '/'">
<img :src="playlist.uploaderAvatar" loading="lazy" class="rounded-full" /> <img :src="playlist.uploaderAvatar" loading="lazy" class="rounded-full" />

View File

@ -1,5 +1,5 @@
<template> <template>
<div ref="scrollable" class="overflow-x-scroll h-screen-sm"> <div ref="scrollable" class="h-screen-sm overflow-x-scroll">
<VideoItem <VideoItem
v-for="(related, index) in playlist.relatedStreams" v-for="(related, index) in playlist.relatedStreams"
:key="related.url" :key="related.url"

View File

@ -1,7 +1,7 @@
<template> <template>
<h2 v-t="'titles.playlists'" class="font-bold my-4" /> <h2 v-t="'titles.playlists'" class="my-4 font-bold" />
<div class="flex justify-between mb-3"> <div class="mb-3 flex justify-between">
<button v-t="'actions.create_playlist'" class="btn" @click="onCreatePlaylist" /> <button v-t="'actions.create_playlist'" class="btn" @click="onCreatePlaylist" />
<div class="flex"> <div class="flex">
<button v-if="playlists.length > 0" v-t="'actions.export_to_json'" class="btn" @click="exportPlaylists" /> <button v-if="playlists.length > 0" v-t="'actions.export_to_json'" class="btn" @click="exportPlaylists" />
@ -29,13 +29,13 @@
</div> </div>
<p <p
style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical" style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical"
class="my-2 overflow-hidden flex link" class="link my-2 flex overflow-hidden"
:title="playlist.name" :title="playlist.name"
v-text="playlist.name" v-text="playlist.name"
/> />
</router-link> </router-link>
<button v-t="'actions.edit_playlist'" class="btn h-auto" @click="showPlaylistEditModal(playlist)" /> <button v-t="'actions.edit_playlist'" class="btn h-auto" @click="showPlaylistEditModal(playlist)" />
<button v-t="'actions.delete_playlist'" class="btn h-auto ml-2" @click="playlistToDelete = playlist.id" /> <button v-t="'actions.delete_playlist'" class="btn ml-2 h-auto" @click="playlistToDelete = playlist.id" />
<ModalComponent v-if="playlist.id == playlistToEdit" @close="playlistToEdit = null"> <ModalComponent v-if="playlist.id == playlistToEdit" @close="playlistToEdit = null">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<h2 v-t="'actions.edit_playlist'" /> <h2 v-t="'actions.edit_playlist'" />
@ -64,7 +64,7 @@
</div> </div>
<hr /> <hr />
<h2 v-t="'titles.bookmarks'" class="font-bold my-4" /> <h2 v-t="'titles.bookmarks'" class="my-4 font-bold" />
<div v-if="bookmarks" class="video-grid"> <div v-if="bookmarks" class="video-grid">
<router-link <router-link
@ -75,18 +75,18 @@
<img class="w-full" :src="playlist.thumbnail" alt="thumbnail" /> <img class="w-full" :src="playlist.thumbnail" alt="thumbnail" />
<div class="relative text-sm"> <div class="relative text-sm">
<span class="thumbnail-overlay thumbnail-right" v-text="`${playlist.videos} ${$t('video.videos')}`" /> <span class="thumbnail-overlay thumbnail-right" v-text="`${playlist.videos} ${$t('video.videos')}`" />
<div class="absolute bottom-100px right-5px px-5px z-100" @click.prevent="removeBookmark(index)"> <div class="absolute bottom-100px right-5px z-100 px-5px" @click.prevent="removeBookmark(index)">
<font-awesome-icon class="ml-3" icon="bookmark" /> <font-awesome-icon class="ml-3" icon="bookmark" />
</div> </div>
</div> </div>
<p <p
style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical" style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical"
class="my-2 overflow-hidden flex link" class="link my-2 flex overflow-hidden"
:title="playlist.name" :title="playlist.name"
v-text="playlist.name" v-text="playlist.name"
/> />
<a :href="playlist.uploaderUrl" class="flex items-center"> <a :href="playlist.uploaderUrl" class="flex items-center">
<img class="rounded-full w-32px h-32px" :src="playlist.uploaderAvatar" /> <img class="h-32px w-32px rounded-full" :src="playlist.uploaderAvatar" />
<span class="ml-3 hover:underline" v-text="playlist.uploader" /> <span class="ml-3 hover:underline" v-text="playlist.uploader" />
</a> </a>
</router-link> </router-link>

View File

@ -4,7 +4,7 @@
<font-awesome-icon icon="chevron-left" /><span v-t="'actions.back'" class="ml-1.5" /> <font-awesome-icon icon="chevron-left" /><span v-t="'actions.back'" class="ml-1.5" />
</button> </button>
</div> </div>
<h1 v-t="'titles.preferences'" class="font-bold text-center" /> <h1 v-t="'titles.preferences'" class="text-center font-bold" />
<hr /> <hr />
<label for="ddlTheme" class="pref"> <label for="ddlTheme" class="pref">
<strong v-t="'actions.theme'" /> <strong v-t="'actions.theme'" />
@ -127,7 +127,7 @@
/> />
</label> </label>
<!-- chapters layout on mobile --> <!-- chapters layout on mobile -->
<label class="lg:invisible pref" for="chkMinimizeChapters"> <label class="pref lg:invisible" for="chkMinimizeChapters">
<strong v-t="'actions.chapters_layout_mobile'" /> <strong v-t="'actions.chapters_layout_mobile'" />
<select id="ddlDefaultHomepage" v-model="mobileChapterLayout" class="select w-auto" @change="onChange($event)"> <select id="ddlDefaultHomepage" v-model="mobileChapterLayout" class="select w-auto" @change="onChange($event)">
@ -184,7 +184,7 @@
<select <select
id="ddlEnabledCodecs" id="ddlEnabledCodecs"
v-model="enabledCodecs" v-model="enabledCodecs"
class="select w-auto h-auto" class="select h-auto w-auto"
multiple multiple
@change="onChange($event)" @change="onChange($event)"
> >
@ -316,7 +316,7 @@
v-model="password" v-model="password"
:placeholder="$t('login.password')" :placeholder="$t('login.password')"
:aria-label="$t('login.password')" :aria-label="$t('login.password')"
class="input w-auto mr-2" class="input mr-2 w-auto"
type="password" type="password"
@keyup.enter="deleteAccount" @keyup.enter="deleteAccount"
/> />

View File

@ -1,5 +1,5 @@
<template> <template>
<h1 v-t="'titles.register'" class="font-bold text-center my-4" /> <h1 v-t="'titles.register'" class="my-4 text-center font-bold" />
<hr /> <hr />
<div class="text-center"> <div class="text-center">
<form class="children:pb-3"> <form class="children:pb-3">

View File

@ -1,5 +1,5 @@
<template> <template>
<h1 class="text-center my-2" v-text="$route.query.search_query" /> <h1 class="my-2 text-center" v-text="$route.query.search_query" />
<label for="ddlSearchFilters"> <label for="ddlSearchFilters">
<strong v-text="`${$t('actions.filter')}:`" /> <strong v-text="`${$t('actions.filter')}:`" />

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="absolute suggestions-container"> <div class="suggestions-container absolute">
<ul> <ul>
<li <li
v-for="(suggestion, i) in searchSuggestions" v-for="(suggestion, i) in searchSuggestions"

View File

@ -13,7 +13,7 @@
<label v-t="'actions.with_timecode'" for="withTimeCode" /> <label v-t="'actions.with_timecode'" for="withTimeCode" />
<input id="withTimeCode" v-model="withTimeCode" type="checkbox" @change="onChange" /> <input id="withTimeCode" v-model="withTimeCode" type="checkbox" @change="onChange" />
</div> </div>
<div v-if="withTimeCode" class="flex justify-between mt-2 items-center"> <div v-if="withTimeCode" class="mt-2 flex items-center justify-between">
<label v-t="'actions.time_code'" /> <label v-t="'actions.time_code'" />
<input v-model="timeStamp" class="input w-12" type="text" @change="onChange" /> <input v-model="timeStamp" class="input w-12" type="text" @change="onChange" />
</div> </div>
@ -21,7 +21,7 @@
<h3 class="mt-4" v-text="generatedLink" /> <h3 class="mt-4" v-text="generatedLink" />
</a> </a>
<QrCode v-if="showQrCode" :text="generatedLink" /> <QrCode v-if="showQrCode" :text="generatedLink" />
<div class="flex justify-end mt-4"> <div class="mt-4 flex justify-end">
<button v-t="'actions.generate_qrcode'" class="btn" @click="showQrCode = !showQrCode" /> <button v-t="'actions.generate_qrcode'" class="btn" @click="showQrCode = !showQrCode" />
<button v-t="'actions.follow_link'" class="btn ml-3" @click="followLink()" /> <button v-t="'actions.follow_link'" class="btn ml-3" @click="followLink()" />
<button v-t="'actions.copy_link'" class="btn ml-3" @click="copyLink()" /> <button v-t="'actions.copy_link'" class="btn ml-3" @click="copyLink()" />

View File

@ -1,7 +1,7 @@
<template> <template>
<h1 v-t="'titles.subscriptions'" class="font-bold text-center my-4" /> <h1 v-t="'titles.subscriptions'" class="my-4 text-center font-bold" />
<!-- import / export section --> <!-- import / export section -->
<div class="flex justify-between w-full"> <div class="w-full flex justify-between">
<div class="flex"> <div class="flex">
<button class="btn mx-1"> <button class="btn mx-1">
<router-link v-t="'actions.import_from_json'" to="/import" /> <router-link v-t="'actions.import_from_json'" to="/import" />
@ -41,16 +41,16 @@
<div <div
v-for="subscription in filteredSubscriptions" v-for="subscription in filteredSubscriptions"
:key="subscription.url" :key="subscription.url"
class="col m-2 p-1 border rounded-lg border-gray-500" class="col m-2 border border-gray-500 rounded-lg p-1"
> >
<router-link :to="subscription.url" class="flex p-2 font-bold text-4x4"> <router-link :to="subscription.url" class="text-4x4 flex p-2 font-bold">
<img :src="subscription.avatar" class="rounded-full h-[fit-content]" width="48" height="48" /> <img :src="subscription.avatar" class="h-[fit-content] rounded-full" width="48" height="48" />
<span class="self-center mx-2" v-text="subscription.name" /> <span class="mx-2 self-center" v-text="subscription.name" />
</router-link> </router-link>
<!-- subscribe / unsubscribe btn --> <!-- subscribe / unsubscribe btn -->
<button <button
v-t="`actions.${subscription.subscribed ? 'unsubscribe' : 'subscribe'}`" v-t="`actions.${subscription.subscribed ? 'unsubscribe' : 'subscribe'}`"
class="btn w-full mt-2" class="btn mt-2 w-full"
@click="handleButton(subscription)" @click="handleButton(subscription)"
/> />
</div> </div>
@ -61,18 +61,18 @@
<h2 v-t="'actions.create_group'" /> <h2 v-t="'actions.create_group'" />
<div class="flex flex-col"> <div class="flex flex-col">
<input v-model="newGroupName" class="input my-4" type="text" :placeholder="$t('actions.group_name')" /> <input v-model="newGroupName" class="input my-4" type="text" :placeholder="$t('actions.group_name')" />
<button v-t="'actions.create_group'" class="ml-auto btn w-max" @click="createGroup()" /> <button v-t="'actions.create_group'" class="btn ml-auto w-max" @click="createGroup()" />
</div> </div>
</ModalComponent> </ModalComponent>
<ModalComponent v-if="showEditGroupModal" @close="showEditGroupModal = false"> <ModalComponent v-if="showEditGroupModal" @close="showEditGroupModal = false">
<div class="flex justify-between mt-3 mb-5"> <div class="mb-5 mt-3 flex justify-between">
<input v-model="editedGroupName" type="text" class="input" /> <input v-model="editedGroupName" type="text" class="input" />
<button v-t="'actions.okay'" class="btn" :placeholder="$t('actions.group_name')" @click="editGroupName()" /> <button v-t="'actions.okay'" class="btn" :placeholder="$t('actions.group_name')" @click="editGroupName()" />
</div> </div>
<div class="flex flex-col mt-3 mb-2 overflow-y-scroll h-70"> <div class="mb-2 mt-3 h-70 flex flex-col overflow-y-scroll">
<div v-for="subscription in subscriptions" :key="subscription.name"> <div v-for="subscription in subscriptions" :key="subscription.name">
<div class="flex justify-between mr-3"> <div class="mr-3 flex justify-between">
<span>{{ subscription.name }}</span> <span>{{ subscription.name }}</span>
<input <input
type="checkbox" type="checkbox"

View File

@ -1,5 +1,5 @@
<template> <template>
<h1 v-t="'titles.trending'" class="font-bold text-center my-4" /> <h1 v-t="'titles.trending'" class="my-4 text-center font-bold" />
<hr /> <hr />

View File

@ -1,7 +1,7 @@
<template> <template>
<div v-if="showVideo" class="flex flex-col flex-justify-between"> <div v-if="showVideo" class="flex flex-col flex-justify-between">
<router-link <router-link
class="focus:underline hover:underline inline-block w-full" class="inline-block w-full focus:underline hover:underline"
:to="{ :to="{
path: '/watch', path: '/watch',
query: { query: {
@ -13,14 +13,14 @@
> >
<div class="w-full"> <div class="w-full">
<img <img
class="w-full aspect-video object-contain" class="aspect-video w-full object-contain"
:src="thumbnail" :src="thumbnail"
:alt="title" :alt="title"
:class="{ 'shorts-img': item.isShort, 'opacity-75': item.watched }" :class="{ 'shorts-img': item.isShort, 'opacity-75': item.watched }"
loading="lazy" loading="lazy"
/> />
<!-- progress bar --> <!-- progress bar -->
<div class="relative w-full h-1"> <div class="relative h-1 w-full">
<div <div
v-if="item.watched && item.duration > 0" v-if="item.watched && item.duration > 0"
class="absolute bottom-0 left-0 h-1 bg-red-600" class="absolute bottom-0 left-0 h-1 bg-red-600"
@ -51,7 +51,7 @@
<div> <div>
<p <p
style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical" style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical"
class="pt-2 overflow-hidden flex link font-bold" class="link flex overflow-hidden pt-2 font-bold"
:title="title" :title="title"
v-text="title" v-text="title"
/> />
@ -64,16 +64,16 @@
v-if="item.uploaderAvatar" v-if="item.uploaderAvatar"
:src="item.uploaderAvatar" :src="item.uploaderAvatar"
loading="lazy" loading="lazy"
class="rounded-full mr-0.5 mt-0.5 w-32px h-32px" class="mr-0.5 mt-0.5 h-32px w-32px rounded-full"
width="68" width="68"
height="68" height="68"
/> />
</router-link> </router-link>
<div class="px-2 flex-1"> <div class="flex-1 px-2">
<router-link <router-link
v-if="item.uploaderUrl && item.uploaderName && !hideChannel" v-if="item.uploaderUrl && item.uploaderName && !hideChannel"
class="link-secondary overflow-hidden block text-sm" class="link-secondary block overflow-hidden text-sm"
:to="item.uploaderUrl" :to="item.uploaderUrl"
:title="item.uploaderName" :title="item.uploaderName"
> >
@ -81,7 +81,7 @@
<font-awesome-icon v-if="item.uploaderVerified" class="ml-1.5" icon="check" /> <font-awesome-icon v-if="item.uploaderVerified" class="ml-1.5" icon="check" />
</router-link> </router-link>
<div v-if="item.views >= 0 || item.uploadedDate" class="text-xs font-normal text-gray-300 mt-1"> <div v-if="item.views >= 0 || item.uploadedDate" class="mt-1 text-xs font-normal text-gray-300">
<span v-if="item.views >= 0"> <span v-if="item.views >= 0">
<font-awesome-icon icon="eye" /> <font-awesome-icon icon="eye" />
<span class="pl-1" v-text="`${numberFormat(item.views)} `" /> <span class="pl-1" v-text="`${numberFormat(item.views)} `" />

View File

@ -2,17 +2,17 @@
<div <div
ref="container" ref="container"
data-shaka-player-container data-shaka-player-container
class="w-full max-h-screen flex justify-center relative" class="relative max-h-screen w-full flex justify-center"
:class="{ 'player-container': !isEmbed }" :class="{ 'player-container': !isEmbed }"
> >
<video ref="videoEl" class="w-full" data-shaka-player :autoplay="shouldAutoPlay" :loop="selectedAutoLoop" /> <video ref="videoEl" class="w-full" data-shaka-player :autoplay="shouldAutoPlay" :loop="selectedAutoLoop" />
<span <span
id="preview-container" id="preview-container"
ref="previewContainer" ref="previewContainer"
class="hidden flex-col absolute bottom-0 z-[2000] mb-[3.5%] items-center" class="absolute bottom-0 z-[2000] mb-[3.5%] hidden flex-col items-center"
> >
<canvas id="preview" ref="preview" class="rounded-sm" /> <canvas id="preview" ref="preview" class="rounded-sm" />
<span class="text-sm mt-2 rounded-xl pb-1 pt-1.5 px-2 bg-dark-700 w-min" v-text="timeFormat(currentTime)" /> <span class="mt-2 w-min rounded-xl bg-dark-700 px-2 pb-1 pt-1.5 text-sm" v-text="timeFormat(currentTime)" />
</span> </span>
<button <button
v-if="inSegment" v-if="inSegment"

View File

@ -17,12 +17,12 @@ export default {
<template> <template>
<template v-if="getPreferenceBoolean('showWatchOnYouTube', false)"> <template v-if="getPreferenceBoolean('showWatchOnYouTube', false)">
<!-- For large screens --> <!-- For large screens -->
<a :href="link" class="btn lt-lg:hidden flex items-center"> <a :href="link" class="btn flex items-center lt-lg:hidden">
<i18n-t keypath="player.watch_on" tag="strong">{{ platform }}</i18n-t> <i18n-t keypath="player.watch_on" tag="strong">{{ platform }}</i18n-t>
<font-awesome-icon class="mx-1.5" :icon="['fab', platform.toLowerCase()]" /> <font-awesome-icon class="mx-1.5" :icon="['fab', platform.toLowerCase()]" />
</a> </a>
<!-- For small screens --> <!-- For small screens -->
<a :href="link" class="btn lg:hidden flex items-center"> <a :href="link" class="btn flex items-center lg:hidden">
<font-awesome-icon class="mx-1.5" :icon="['fab', platform.toLowerCase()]" /> <font-awesome-icon class="mx-1.5" :icon="['fab', platform.toLowerCase()]" />
</a> </a>
</template> </template>

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-if="video && isEmbed" class="absolute top-0 left-0 h-full w-full bg-black z-50"> <div v-if="video && isEmbed" class="absolute left-0 top-0 z-50 h-full w-full bg-black">
<VideoPlayer <VideoPlayer
ref="videoPlayer" ref="videoPlayer"
:video="video" :video="video"
@ -41,8 +41,8 @@
/> />
</div> </div>
<!-- video title --> <!-- video title -->
<div class="font-bold mt-2 text-2xl break-words" v-text="video.title" /> <div class="mt-2 break-words text-2xl font-bold" v-text="video.title" />
<div class="flex flex-wrap mt-3 mb-3"> <div class="mb-3 mt-3 flex flex-wrap">
<!-- views / date --> <!-- views / date -->
<div class="flex flex-auto gap-2"> <div class="flex flex-auto gap-2">
<span v-t="{ path: 'video.views', args: { views: addCommas(video.views) } }" /> <span v-t="{ path: 'video.views', args: { views: addCommas(video.views) } }" />
@ -93,7 +93,7 @@
:playlist-index="index" :playlist-index="index"
@close="showShareModal = !showShareModal" @close="showShareModal = !showShareModal"
/> />
<div class="flex flex-wrap gap-1 ml-auto"> <div class="ml-auto flex flex-wrap gap-1">
<!-- Subscribe Button --> <!-- Subscribe Button -->
<button class="btn flex items-center" @click="showModal = !showModal"> <button class="btn flex items-center" @click="showModal = !showModal">
{{ $t("actions.add_to_playlist") }}<font-awesome-icon class="ml-1" icon="circle-plus" /> {{ $t("actions.add_to_playlist") }}<font-awesome-icon class="ml-1" icon="circle-plus" />
@ -150,7 +150,7 @@
<div <div
v-for="metaInfo in video?.metaInfo ?? []" v-for="metaInfo in video?.metaInfo ?? []"
:key="metaInfo.title" :key="metaInfo.title"
class="btn px-4 py-2 flex flex-wrap gap-2 my-3 cursor-default" class="btn my-3 flex flex-wrap cursor-default gap-2 px-4 py-2"
> >
<span>{{ metaInfo.description ?? metaInfo.title }}</span> <span>{{ metaInfo.description ?? metaInfo.title }}</span>
<a v-for="(link, linkIndex) in metaInfo.urls" :key="linkIndex" :href="link" class="underline">{{ <a v-for="(link, linkIndex) in metaInfo.urls" :key="linkIndex" :href="link" class="underline">{{
@ -172,7 +172,7 @@
<template v-if="showDesc"> <template v-if="showDesc">
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<div class="break-words description" v-html="purifiedDescription" /> <div class="description break-words" v-html="purifiedDescription" />
<br /> <br />
<div <div
@ -183,11 +183,11 @@
<div v-text="`${$t('video.license')}: ${video.license}`" /> <div v-text="`${$t('video.license')}: ${video.license}`" />
<div class="capitalize" v-text="`${$t('video.visibility')}: ${video.visibility}`" /> <div class="capitalize" v-text="`${$t('video.visibility')}: ${video.visibility}`" />
<div v-if="video.tags" class="flex flex-wrap gap-2 mt-2"> <div v-if="video.tags" class="mt-2 flex flex-wrap gap-2">
<router-link <router-link
v-for="tag in video.tags" v-for="tag in video.tags"
:key="tag" :key="tag"
class="rounded-s px-2 py-1 btn line-clamp-1" class="btn line-clamp-1 rounded-s px-2 py-1"
:to="`/results?search_query=${encodeURIComponent(tag)}`" :to="`/results?search_query=${encodeURIComponent(tag)}`"
>{{ tag }}</router-link >{{ tag }}</router-link
> >
@ -205,8 +205,8 @@
<hr /> <hr />
<div class="grid xl:grid-cols-5 sm:grid-cols-4 grid-cols-1"> <div class="grid grid-cols-1 sm:grid-cols-4 xl:grid-cols-5">
<div class="xl:col-span-4 sm:col-span-3"> <div class="sm:col-span-3 xl:col-span-4">
<button <button
v-if="!comments?.disabled" v-if="!comments?.disabled"
class="btn mb-2" class="btn mb-2"
@ -218,14 +218,14 @@
" "
/> />
</div> </div>
<div v-if="!showComments" class="xl:col-span-4 sm:col-span-3"></div> <div v-if="!showComments" class="sm:col-span-3 xl:col-span-4"></div>
<div v-else-if="!comments" class="xl:col-span-4 sm:col-span-3"> <div v-else-if="!comments" class="sm:col-span-3 xl:col-span-4">
<p v-t="'comment.loading'" class="text-center mt-8"></p> <p v-t="'comment.loading'" class="mt-8 text-center"></p>
</div> </div>
<div v-else-if="comments.disabled" class="xl:col-span-4 sm:col-span-3"> <div v-else-if="comments.disabled" class="sm:col-span-3 xl:col-span-4">
<p v-t="'comment.disabled'" class="text-center mt-8"></p> <p v-t="'comment.disabled'" class="mt-8 text-center"></p>
</div> </div>
<div v-else ref="comments" class="xl:col-span-4 sm:col-span-3"> <div v-else ref="comments" class="sm:col-span-3 xl:col-span-4">
<CommentItem <CommentItem
v-for="comment in comments.comments" v-for="comment in comments.comments"
:key="comment.commentId" :key="comment.commentId"