1
0
mirror of https://github.com/TeamPiped/Piped.git synced 2024-12-12 21:30:27 +05:30

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: {
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-solid": "1.1.15",
"@intlify/unplugin-vue-i18n": "0.12.2",
"@unocss/eslint-config": "0.55.0",
"@unocss/preset-icons": "0.55.0",
"@unocss/preset-uno": "0.55.0",
"@unocss/preset-web-fonts": "0.55.0",

143
pnpm-lock.yaml generated
View File

@ -70,6 +70,9 @@ devDependencies:
'@intlify/unplugin-vue-i18n':
specifier: 0.12.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':
specifier: 0.55.0
version: 0.55.0
@ -1953,10 +1956,75 @@ packages:
'@types/node': 20.4.8
dev: true
/@types/semver@7.5.0:
resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==}
dev: true
/@types/trusted-types@2.0.3:
resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==}
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):
resolution: {integrity: sha512-Qqk8zONPBBigEcUOGhEwBPIQmWnQGpjpQrSdpjs86BphKbQcqWHES1fQA83Fk2tpZ08zo0zAPDJ8VhfR+c+yqg==}
peerDependencies:
@ -2007,6 +2075,32 @@ packages:
resolution: {integrity: sha512-TcTugpuhsv6OwMsP3iFIG8FVc9N5JzkojIGNAKF8I2WBftZ//3QcpEHiHc1mH3MlPYfJgUvCcT6/Gad55qmHzg==}
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:
resolution: {integrity: sha512-FCel+gJ3N8C/361yQ3gYTmbCjX3DXQ+LdxBiAawapbtTA4eXw55/f7cpiiWcHoouCRrWIEMOQN5DskAJvmMaTw==}
dependencies:
@ -2340,6 +2434,11 @@ packages:
is-array-buffer: 3.0.2
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:
resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==}
engines: {node: '>= 0.4'}
@ -2713,6 +2812,13 @@ packages:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
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:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
engines: {node: '>=6.0.0'}
@ -3299,6 +3405,18 @@ packages:
define-properties: 1.2.0
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:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
dependencies:
@ -4140,6 +4258,11 @@ packages:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true
/path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
dev: true
/pathe@1.1.1:
resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
dev: true
@ -4482,6 +4605,11 @@ packages:
totalist: 3.0.1
dev: true
/slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
dev: true
/source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
@ -4692,6 +4820,15 @@ packages:
punycode: 2.3.0
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:
resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
dev: true
@ -4751,6 +4888,12 @@ packages:
is-typed-array: 1.1.12
dev: true
/typescript@5.1.6:
resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
/ufo@1.2.0:
resolution: {integrity: sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==}
dev: true

View File

@ -1,5 +1,5 @@
<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">
<NavBar />
<router-view v-slot="{ Component }">

View File

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

View File

@ -5,13 +5,13 @@
<img
v-if="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"
/>
<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">
<img height="48" width="48" class="rounded-full m-1" :src="channel.avatarUrl" />
<div class="flex gap-1 items-center">
<img height="48" width="48" class="m-1 rounded-full" :src="channel.avatarUrl" />
<div class="flex items-center gap-1">
<h1 class="!text-xl" v-text="channel.name" />
<font-awesome-icon v-if="channel.verified" class="!text-xl" icon="check" />
</div>
@ -46,7 +46,7 @@
<WatchOnButton :link="`https://youtube.com/channel/${channel.id}`" />
<div class="flex my-2 mx-1">
<div class="mx-1 my-2 flex">
<button
v-for="(tab, index) in tabs"
:key="tab.name"

View File

@ -1,6 +1,6 @@
<template>
<!-- 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">
{{ $t("video.chapters") }} ({{ chapters.length }})
</h2>
@ -12,9 +12,9 @@
@click="$emit('seek', chapter.start)"
>
<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" />
<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 font-bold text-blue-500" v-text="timeFormat(chapter.start)" />
</div>
@ -25,7 +25,7 @@
<!-- mobile vertical view -->
<div
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">
{{ $t("video.chapters") }} ({{ chapters.length }})
@ -38,9 +38,9 @@
@click="$emit('seek', chapter.start)"
>
<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" />
<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 font-bold text-blue-500" v-text="timeFormat(chapter.start)" />
</div>

View File

@ -1,5 +1,5 @@
<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 -->
<span v-if="showFullText" v-html="fullText()" />
<!-- eslint-disable-next-line vue/no-v-html -->
@ -7,7 +7,7 @@
<span v-if="text.length > 100 && !showFullText">...</span>
<button
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"
>
[{{ showFullText ? $t("actions.show_less") : $t("actions.show_more") }}]

View File

@ -1,8 +1,8 @@
<template>
<div class="comment flex mt-1.5">
<div class="comment mt-1.5 flex">
<img
:src="comment.thumbnail"
class="comment-avatar rounded-full w-12 h-12"
class="comment-avatar h-12 w-12 rounded-full"
height="48"
width="48"
loading="lazy"
@ -23,10 +23,10 @@
</div>
<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" />
</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>
<!-- eslint-disable-next-line vue/no-v-html -->
<div class="whitespace-pre-wrap" v-html="purifiedText" />

View File

@ -2,7 +2,7 @@
<ModalComponent @close="$emit('close')">
<div>
<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.okay'" class="btn" @click="$emit('confirm')" />
</div>

View File

@ -1,7 +1,7 @@
<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>
<label for="filters">
<strong v-text="`${$t('actions.filter')}:`" />

View File

@ -1,5 +1,5 @@
<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">
<font-awesome-icon :icon="['fab', 'github']" />
<span v-t="'actions.source_code'" class="ml-2" />

View File

@ -1,21 +1,21 @@
<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 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.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)" />
</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" />
<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: '3' } }" value="3" />
<option v-t="{ path: 'info.hours', args: { amount: '6' } }" value="6" />

View File

@ -1,5 +1,5 @@
<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" />
</div>
<div v-else>

View File

@ -1,5 +1,5 @@
<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 />
<div class="text-center">
<form class="children:pb-3">

View File

@ -1,21 +1,21 @@
<template>
<nav class="flex flex-wrap items-center justify-center px-2 sm:px-4 pb-2.5 w-full relative">
<div class="flex-1 flex justify-start">
<router-link class="flex font-bold text-3xl items-center font-sans" :to="homePagePath"
<nav class="relative w-full flex flex-wrap items-center justify-center px-2 pb-2.5 sm:px-4">
<div class="flex flex-1 justify-start">
<router-link class="flex items-center text-3xl font-bold font-sans" :to="homePagePath"
><img
alt="logo"
src="/img/icons/logo.svg"
height="32"
width="32"
class="w-10 mr-[-0.6rem]"
class="mr-[-0.6rem] w-10"
/>iped</router-link
>
</div>
<div class="lt-md:hidden search-container">
<div class="search-container lt-md:hidden">
<input
ref="videoSearch"
v-model="searchText"
class="input w-72 h-10 pr-20"
class="input h-10 w-72 pr-20"
type="text"
role="search"
:title="$t('actions.search')"
@ -31,13 +31,13 @@
<div class="i-fa6-solid:magnifying-glass"></div>
</button>
<!-- 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>
</button>
<!-- 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">
<router-link v-t="'titles.trending'" to="/trending" />
</li>
@ -64,7 +64,7 @@
<!-- navigation bar for mobile devices -->
<div
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">
<div class="i-fa6-solid:fire"></div>
@ -96,7 +96,7 @@
</router-link>
</div>
<!-- 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
v-model="searchText"
class="input h-10 w-full"

View File

@ -1,5 +1,5 @@
<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>
<h2 v-t="'info.page_not_found'" class="!text-2xl" />
<a v-t="'actions.back_to_home'" class="btn mt-16" href="/" />

View File

@ -1,10 +1,10 @@
<template>
<ModalComponent>
<span v-t="'actions.select_playlist'" class="text-2xl w-max inline-block" />
<select v-model="selectedPlaylist" class="select w-full mt-3">
<span v-t="'actions.select_playlist'" class="inline-block w-max text-2xl" />
<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" />
</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"

View File

@ -2,11 +2,11 @@
<ErrorHandler v-if="playlist && playlist.error" :message="playlist.message" :error="playlist.error" />
<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" />
<div class="flex justify-between items-center mt-1">
<div class="mt-1 flex items-center justify-between">
<div>
<router-link class="link flex items-center gap-3" :to="playlist.uploaderUrl || '/'">
<img :src="playlist.uploaderAvatar" loading="lazy" class="rounded-full" />

View File

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

View File

@ -1,7 +1,7 @@
<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" />
<div class="flex">
<button v-if="playlists.length > 0" v-t="'actions.export_to_json'" class="btn" @click="exportPlaylists" />
@ -29,13 +29,13 @@
</div>
<p
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"
v-text="playlist.name"
/>
</router-link>
<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">
<div class="flex flex-col gap-2">
<h2 v-t="'actions.edit_playlist'" />
@ -64,7 +64,7 @@
</div>
<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">
<router-link
@ -75,18 +75,18 @@
<img class="w-full" :src="playlist.thumbnail" alt="thumbnail" />
<div class="relative text-sm">
<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" />
</div>
</div>
<p
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"
v-text="playlist.name"
/>
<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" />
</a>
</router-link>

View File

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

View File

@ -1,5 +1,5 @@
<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 />
<div class="text-center">
<form class="children:pb-3">

View File

@ -1,5 +1,5 @@
<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">
<strong v-text="`${$t('actions.filter')}:`" />

View File

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

View File

@ -13,7 +13,7 @@
<label v-t="'actions.with_timecode'" for="withTimeCode" />
<input id="withTimeCode" v-model="withTimeCode" type="checkbox" @change="onChange" />
</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'" />
<input v-model="timeStamp" class="input w-12" type="text" @change="onChange" />
</div>
@ -21,7 +21,7 @@
<h3 class="mt-4" v-text="generatedLink" />
</a>
<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.follow_link'" class="btn ml-3" @click="followLink()" />
<button v-t="'actions.copy_link'" class="btn ml-3" @click="copyLink()" />

View File

@ -1,7 +1,7 @@
<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 -->
<div class="flex justify-between w-full">
<div class="w-full flex justify-between">
<div class="flex">
<button class="btn mx-1">
<router-link v-t="'actions.import_from_json'" to="/import" />
@ -41,16 +41,16 @@
<div
v-for="subscription in filteredSubscriptions"
: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">
<img :src="subscription.avatar" class="rounded-full h-[fit-content]" width="48" height="48" />
<span class="self-center mx-2" v-text="subscription.name" />
<router-link :to="subscription.url" class="text-4x4 flex p-2 font-bold">
<img :src="subscription.avatar" class="h-[fit-content] rounded-full" width="48" height="48" />
<span class="mx-2 self-center" v-text="subscription.name" />
</router-link>
<!-- subscribe / unsubscribe btn -->
<button
v-t="`actions.${subscription.subscribed ? 'unsubscribe' : 'subscribe'}`"
class="btn w-full mt-2"
class="btn mt-2 w-full"
@click="handleButton(subscription)"
/>
</div>
@ -61,18 +61,18 @@
<h2 v-t="'actions.create_group'" />
<div class="flex flex-col">
<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>
</ModalComponent>
<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" />
<button v-t="'actions.okay'" class="btn" :placeholder="$t('actions.group_name')" @click="editGroupName()" />
</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 class="flex justify-between mr-3">
<div class="mr-3 flex justify-between">
<span>{{ subscription.name }}</span>
<input
type="checkbox"

View File

@ -1,5 +1,5 @@
<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 />

View File

@ -1,7 +1,7 @@
<template>
<div v-if="showVideo" class="flex flex-col flex-justify-between">
<router-link
class="focus:underline hover:underline inline-block w-full"
class="inline-block w-full focus:underline hover:underline"
:to="{
path: '/watch',
query: {
@ -13,14 +13,14 @@
>
<div class="w-full">
<img
class="w-full aspect-video object-contain"
class="aspect-video w-full object-contain"
:src="thumbnail"
:alt="title"
:class="{ 'shorts-img': item.isShort, 'opacity-75': item.watched }"
loading="lazy"
/>
<!-- progress bar -->
<div class="relative w-full h-1">
<div class="relative h-1 w-full">
<div
v-if="item.watched && item.duration > 0"
class="absolute bottom-0 left-0 h-1 bg-red-600"
@ -51,7 +51,7 @@
<div>
<p
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"
v-text="title"
/>
@ -64,16 +64,16 @@
v-if="item.uploaderAvatar"
:src="item.uploaderAvatar"
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"
height="68"
/>
</router-link>
<div class="px-2 flex-1">
<div class="flex-1 px-2">
<router-link
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"
:title="item.uploaderName"
>
@ -81,7 +81,7 @@
<font-awesome-icon v-if="item.uploaderVerified" class="ml-1.5" icon="check" />
</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">
<font-awesome-icon icon="eye" />
<span class="pl-1" v-text="`${numberFormat(item.views)} `" />

View File

@ -2,17 +2,17 @@
<div
ref="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 }"
>
<video ref="videoEl" class="w-full" data-shaka-player :autoplay="shouldAutoPlay" :loop="selectedAutoLoop" />
<span
id="preview-container"
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" />
<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>
<button
v-if="inSegment"

View File

@ -17,12 +17,12 @@ export default {
<template>
<template v-if="getPreferenceBoolean('showWatchOnYouTube', false)">
<!-- 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>
<font-awesome-icon class="mx-1.5" :icon="['fab', platform.toLowerCase()]" />
</a>
<!-- 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()]" />
</a>
</template>

View File

@ -1,5 +1,5 @@
<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
ref="videoPlayer"
:video="video"
@ -41,8 +41,8 @@
/>
</div>
<!-- video title -->
<div class="font-bold mt-2 text-2xl break-words" v-text="video.title" />
<div class="flex flex-wrap mt-3 mb-3">
<div class="mt-2 break-words text-2xl font-bold" v-text="video.title" />
<div class="mb-3 mt-3 flex flex-wrap">
<!-- views / date -->
<div class="flex flex-auto gap-2">
<span v-t="{ path: 'video.views', args: { views: addCommas(video.views) } }" />
@ -93,7 +93,7 @@
:playlist-index="index"
@close="showShareModal = !showShareModal"
/>
<div class="flex flex-wrap gap-1 ml-auto">
<div class="ml-auto flex flex-wrap gap-1">
<!-- Subscribe Button -->
<button class="btn flex items-center" @click="showModal = !showModal">
{{ $t("actions.add_to_playlist") }}<font-awesome-icon class="ml-1" icon="circle-plus" />
@ -150,7 +150,7 @@
<div
v-for="metaInfo in video?.metaInfo ?? []"
: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>
<a v-for="(link, linkIndex) in metaInfo.urls" :key="linkIndex" :href="link" class="underline">{{
@ -172,7 +172,7 @@
<template v-if="showDesc">
<!-- 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 />
<div
@ -183,11 +183,11 @@
<div v-text="`${$t('video.license')}: ${video.license}`" />
<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
v-for="tag in video.tags"
: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)}`"
>{{ tag }}</router-link
>
@ -205,8 +205,8 @@
<hr />
<div class="grid xl:grid-cols-5 sm:grid-cols-4 grid-cols-1">
<div class="xl:col-span-4 sm:col-span-3">
<div class="grid grid-cols-1 sm:grid-cols-4 xl:grid-cols-5">
<div class="sm:col-span-3 xl:col-span-4">
<button
v-if="!comments?.disabled"
class="btn mb-2"
@ -218,14 +218,14 @@
"
/>
</div>
<div v-if="!showComments" class="xl:col-span-4 sm:col-span-3"></div>
<div v-else-if="!comments" class="xl:col-span-4 sm:col-span-3">
<p v-t="'comment.loading'" class="text-center mt-8"></p>
<div v-if="!showComments" class="sm:col-span-3 xl:col-span-4"></div>
<div v-else-if="!comments" class="sm:col-span-3 xl:col-span-4">
<p v-t="'comment.loading'" class="mt-8 text-center"></p>
</div>
<div v-else-if="comments.disabled" class="xl:col-span-4 sm:col-span-3">
<p v-t="'comment.disabled'" class="text-center mt-8"></p>
<div v-else-if="comments.disabled" class="sm:col-span-3 xl:col-span-4">
<p v-t="'comment.disabled'" class="mt-8 text-center"></p>
</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
v-for="comment in comments.comments"
:key="comment.commentId"