mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-08-14 23:57:27 +00:00
fix it
This commit is contained in:
commit
c8d7ceaea4
36 changed files with 1046 additions and 362 deletions
2
.github/workflows/ipfs-build.yml
vendored
2
.github/workflows/ipfs-build.yml
vendored
|
@ -18,7 +18,7 @@ jobs:
|
|||
cache: "yarn"
|
||||
- run: yarn install --prefer-offline
|
||||
- run: yarn build && sed -i 's/fonts.gstatic.com/fonts.kavin.rocks/g' dist/assets/*.css && cp dist/index.html dist/ipfs-404.html
|
||||
- uses: aquiladev/ipfs-action@v0.3.0-alpha.1
|
||||
- uses: aquiladev/ipfs-action@v0.3.1-alpha.2
|
||||
id: ipfs-add
|
||||
with:
|
||||
path: ./dist
|
||||
|
|
|
@ -127,7 +127,8 @@ Contributions in any other form are also welcomed.
|
|||
# Made with Piped
|
||||
|
||||
- [Yattee](https://github.com/yattee/yattee) - an alternative frontend for YouTube, for IOS.
|
||||
- [LibreTube](https://github.com/Libre-tube/LibreTube) [WIP] - an alternative frontend for YouTube, for Android.
|
||||
- [LibreTube](https://github.com/Libre-tube/LibreTube) - an alternative frontend for YouTube, for Android.
|
||||
- [Hyperpipe](https://codeberg.org/Hyperpipe/Hyperpipe) - an alternative privacy respecting frontend for YouTube Music.
|
||||
|
||||
## YourKit
|
||||
|
||||
|
|
31
package.json
31
package.json
|
@ -9,37 +9,42 @@
|
|||
"lint": "eslint --fix --color --ignore-path .gitignore --ext .js,.vue ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.1.2",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.1.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.1.2",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.2.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.2.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.2.0",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.1",
|
||||
"buffer": "^6.0.3",
|
||||
"dompurify": "^2.3.12",
|
||||
"hotkeys-js": "^3.9.4",
|
||||
"dompurify": "^2.4.0",
|
||||
"hotkeys-js": "^3.10.0",
|
||||
"javascript-time-ago": "^2.5.7",
|
||||
"mux.js": "^6.2.0",
|
||||
"shaka-player": "4.2.0",
|
||||
"shaka-player": "4.2.1",
|
||||
"stream": "^0.0.2",
|
||||
"vue": "^3.2.37",
|
||||
"vue": "^3.2.38",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-router": "^4.1.4",
|
||||
"vue-router": "^4.1.5",
|
||||
"xml-js": "^1.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "^2.1.103",
|
||||
"@intlify/vite-plugin-vue-i18n": "^6.0.1",
|
||||
"@unocss/preset-icons": "^0.45.13",
|
||||
"@unocss/preset-web-fonts": "^0.45.7",
|
||||
"@unocss/transformer-directives": "^0.45.7",
|
||||
"@unocss/transformer-variant-group": "^0.45.13",
|
||||
"@vitejs/plugin-legacy": "^1.8.2",
|
||||
"@vitejs/plugin-vue": "^2.3.4",
|
||||
"@vue/compiler-sfc": "3.2.37",
|
||||
"@vue/compiler-sfc": "3.2.38",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-vue": "^9.3.0",
|
||||
"eslint-plugin-vue": "^9.4.0",
|
||||
"prettier": "^2.7.1",
|
||||
"unocss": "^0.45.18",
|
||||
"vite": "^2.9.14",
|
||||
"vite-plugin-eslint": "^1.7.0",
|
||||
"vite-plugin-pwa": "^0.12.3",
|
||||
"vite-plugin-windicss": "^1.8.7"
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-plugin-pwa": "^0.12.7"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
|
19
src/App.vue
19
src/App.vue
|
@ -102,11 +102,11 @@ b {
|
|||
}
|
||||
|
||||
.video-grid {
|
||||
@apply grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 col-auto <md:gap-x-2.5 md:gap-x-1vw gap-y-1.5;
|
||||
@apply grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 col-auto lt-md:gap-x-2.5 md:gap-x-1vw gap-y-1.5;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@apply h-full py-2 <md:(px-2) md:(px-4) rounded cursor-pointer;
|
||||
@apply h-full py-2 lt-md:px-2 md:px-4 rounded cursor-pointer;
|
||||
}
|
||||
|
||||
.reset {
|
||||
|
@ -114,7 +114,7 @@ b {
|
|||
}
|
||||
|
||||
.auto {
|
||||
@apply dark:(text-white bg-dark-900);
|
||||
@apply @dark:(text-white bg-dark-900);
|
||||
}
|
||||
|
||||
.dark {
|
||||
|
@ -145,13 +145,18 @@ b {
|
|||
.auto .input,
|
||||
.auto .select,
|
||||
.auto .btn {
|
||||
@apply dark:(text-gray-400 bg-dark-400);
|
||||
@apply @dark:(text-gray-400 bg-dark-400);
|
||||
}
|
||||
|
||||
.input {
|
||||
@apply pl-2.5;
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
@apply border-2 border-red-500 outline-none;
|
||||
box-shadow: 0 0 15px rgba(239, 68, 68, var(--un-border-opacity));
|
||||
}
|
||||
|
||||
hr {
|
||||
@apply !mt-2 !mb-3 border-gray-300;
|
||||
}
|
||||
|
@ -161,7 +166,7 @@ hr {
|
|||
}
|
||||
|
||||
.auto hr {
|
||||
@apply dark:border-dark-100;
|
||||
@apply @dark:border-dark-100;
|
||||
}
|
||||
|
||||
h1,
|
||||
|
@ -194,7 +199,7 @@ h2 {
|
|||
}
|
||||
|
||||
.auto .link {
|
||||
@apply dark:hover:(text-gray-300 underline underline-gray-300);
|
||||
@apply @dark:hover:(text-gray-300 underline underline-gray-300);
|
||||
}
|
||||
|
||||
.dark .link-secondary {
|
||||
|
@ -202,7 +207,7 @@ h2 {
|
|||
}
|
||||
|
||||
.auto .link-secondary {
|
||||
@apply dark:(text-gray-300 hover:(text-gray-400 underline underline-gray-400));
|
||||
@apply @dark:(text-gray-300 hover:(text-gray-400 underline underline-gray-400));
|
||||
}
|
||||
|
||||
.line {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<!-- desktop view -->
|
||||
<div v-if="!mobileLayout" class="flex-col overflow-y-scroll max-h-75vh min-h-64 <lg:hidden">
|
||||
<div v-if="!mobileLayout" class="flex-col overflow-y-scroll max-h-75vh min-h-64 lt-lg:hidden">
|
||||
<h2 class="mb-2 bg-gray-500/50 p-2" aria-label="chapters" title="chapters">
|
||||
{{ $t("video.chapters") }} ({{ chapters.length }})
|
||||
</h2>
|
||||
|
@ -45,16 +45,17 @@
|
|||
}
|
||||
.chapter {
|
||||
@apply cursor-pointer self-center p-2.5;
|
||||
img {
|
||||
@apply w-full h-full;
|
||||
}
|
||||
.chapter img {
|
||||
@apply w-full h-full;
|
||||
}
|
||||
.chapter-vertical {
|
||||
@apply cursor-pointer self-center p-2.5;
|
||||
img {
|
||||
}
|
||||
.chapter-vertical img {
|
||||
@apply w-3/10 h-3/10;
|
||||
}
|
||||
}
|
||||
|
||||
.chapter-vertical:hover {
|
||||
@apply bg-gray-500;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
<div class="comment-meta text-sm mb-1.5" v-text="comment.commentedTime" />
|
||||
</div>
|
||||
<div class="whitespace-pre-wrap" v-text="comment.commentText" />
|
||||
<div class="comment-footer mt-1">
|
||||
<font-awesome-icon icon="thumbs-up" />
|
||||
<div class="comment-footer mt-1 flex">
|
||||
<div class="i-fa-solid:thumbs-up" />
|
||||
<span class="ml-1" v-text="numberFormat(comment.likeCount)" />
|
||||
<font-awesome-icon class="ml-1" v-if="comment.hearted" icon="heart" />
|
||||
</div>
|
||||
|
|
42
src/components/ModalComponent.vue
Normal file
42
src/components/ModalComponent.vue
Normal file
|
@ -0,0 +1,42 @@
|
|||
<template>
|
||||
<div class="modal">
|
||||
<div>
|
||||
<div class="modal-container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
window.addEventListener("keydown", this.handleKeyDown);
|
||||
},
|
||||
unmounted() {
|
||||
window.removeEventListener("keydown", this.handleKeyDown);
|
||||
},
|
||||
methods: {
|
||||
handleKeyDown(event) {
|
||||
if (event.code === "Escape") {
|
||||
this.$emit("close");
|
||||
} else return;
|
||||
event.preventDefault();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.modal {
|
||||
@apply fixed z-50 top-0 left-0 w-full h-full bg-dark-900 bg-opacity-80 transition-opacity table;
|
||||
}
|
||||
|
||||
.modal > div {
|
||||
@apply table-cell align-middle;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
@apply w-min m-auto px-8 bg-dark-700 p-6 rounded-xl min-w-[20vw];
|
||||
}
|
||||
</style>
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<nav class="flex flex-wrap items-center justify-center px-2 sm:px-4 py-2.5 w-full relative">
|
||||
<div class="flex-1 flex justify-start">
|
||||
<router-link class="flex font-bold text-3xl items-center font-sans font-bold" to="/"
|
||||
<router-link class="flex font-bold text-3xl items-center font-sans" to="/"
|
||||
><img
|
||||
alt="logo"
|
||||
src="/img/icons/logo.svg"
|
||||
|
@ -11,10 +11,10 @@
|
|||
/>iped</router-link
|
||||
>
|
||||
</div>
|
||||
<div class="<md:hidden">
|
||||
<div class="lt-md:hidden">
|
||||
<input
|
||||
v-model="searchText"
|
||||
class="input !w-72 !h-10"
|
||||
class="input w-72 h-10"
|
||||
type="text"
|
||||
role="search"
|
||||
ref="videoSearch"
|
||||
|
@ -89,7 +89,7 @@
|
|||
<div class="w-{full - 4} md:hidden mx-2">
|
||||
<input
|
||||
v-model="searchText"
|
||||
class="input !h-10 !w-full"
|
||||
class="input h-10 w-full"
|
||||
type="text"
|
||||
role="search"
|
||||
:title="$t('actions.search')"
|
||||
|
@ -174,9 +174,3 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.input:focus {
|
||||
@apply border-2 border-red-500;
|
||||
box-shadow: 0 0 15px rgba(239, 68, 68, var(--tw-border-opacity));
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,46 +1,30 @@
|
|||
<template>
|
||||
<div class="modal">
|
||||
<div>
|
||||
<div class="modal-container">
|
||||
<ModalComponent>
|
||||
<div class="flex">
|
||||
<span class="text-2xl w-max inline-block" v-t="'actions.select_playlist'" />
|
||||
<button class="ml-3" @click="$emit('close')"><font-awesome-icon icon="xmark" /></button>
|
||||
</div>
|
||||
<select class="select w-full" v-model="selectedPlaylist">
|
||||
<option
|
||||
v-for="playlist in playlists"
|
||||
:value="playlist.id"
|
||||
:key="playlist.id"
|
||||
v-text="playlist.name"
|
||||
/>
|
||||
<select class="select w-full mt-3" v-model="selectedPlaylist">
|
||||
<option v-for="playlist in playlists" :value="playlist.id" :key="playlist.id" v-text="playlist.name" />
|
||||
</select>
|
||||
<div class="flex justify-end mt-3">
|
||||
<button
|
||||
class="btn mt-2"
|
||||
class="btn"
|
||||
@click="handleClick(selectedPlaylist)"
|
||||
ref="addButton"
|
||||
v-t="'actions.add_to_playlist'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalComponent>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.modal {
|
||||
@apply fixed z-50 top-0 left-0 w-full h-full bg-dark-900 bg-opacity-80 transition-opacity table;
|
||||
}
|
||||
|
||||
.modal > div {
|
||||
@apply table-cell align-middle;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
@apply w-min m-auto px-8 bg-dark-700 p-6;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ModalComponent from "./ModalComponent.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ModalComponent,
|
||||
},
|
||||
props: {
|
||||
videoId: {
|
||||
type: String,
|
||||
|
@ -65,12 +49,10 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
handleKeyDown(event) {
|
||||
if (event.code === "Escape") {
|
||||
this.$emit("close");
|
||||
} else if (event.code === "Enter") {
|
||||
if (event.code === "Enter") {
|
||||
this.handleClick(this.selectedPlaylist);
|
||||
} else return;
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
handleClick(playlistId) {
|
||||
if (!playlistId) {
|
||||
|
|
|
@ -53,7 +53,7 @@ export default {
|
|||
this.fetchJson(this.authApiUrl() + "/user/playlists/rename", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
playlist: id,
|
||||
playlistId: id,
|
||||
newName: newName,
|
||||
}),
|
||||
headers: {
|
||||
|
|
|
@ -294,7 +294,7 @@
|
|||
<th v-t="'preferences.instance_locations'" />
|
||||
<th v-t="'preferences.has_cdn'" />
|
||||
<th v-t="'preferences.registered_users'" />
|
||||
<th class="<md:(hidden)" v-t="'preferences.version'" />
|
||||
<th class="lt-md:hidden" v-t="'preferences.version'" />
|
||||
<th v-t="'preferences.up_to_date'" />
|
||||
<th v-t="'preferences.ssl_score'" />
|
||||
</tr>
|
||||
|
@ -305,7 +305,7 @@
|
|||
<td v-text="instance.locations" />
|
||||
<td v-text="`${instance.cdn ? '✅' : '❌'}`" />
|
||||
<td v-text="instance.registered" />
|
||||
<td class="<md:(hidden)" v-text="instance.version" />
|
||||
<td class="lt-md:hidden" v-text="instance.version" />
|
||||
<td v-text="`${instance.up_to_date ? '✅' : '❌'}`" />
|
||||
<td>
|
||||
<a :href="sslScore(instance.api_url)" target="_blank" v-t="'actions.view_ssl_score'" />
|
||||
|
@ -616,6 +616,6 @@ export default {
|
|||
|
||||
<style>
|
||||
.pref {
|
||||
@apply flex justify-between items-center my-2 mx-[15vw] <md:(mx-[2vw]);
|
||||
@apply flex justify-between items-center my-2 mx-[15vw] lt-md:mx-[2vw];
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -77,7 +77,7 @@ export default {
|
|||
|
||||
<style>
|
||||
.suggestions-container {
|
||||
@apply left-1/2 translate-x-[-50%] transform-gpu max-w-3xl w-full box-border p-y-1.25 z-10 <md:max-w-[calc(100%-0.5rem)] bg-gray-300;
|
||||
@apply left-1/2 translate-x-[-50%] transform-gpu max-w-3xl w-full box-border p-y-1.25 z-10 lt-md:max-w-[calc(100%-0.5rem)] bg-gray-300;
|
||||
}
|
||||
|
||||
.dark .suggestions-container {
|
||||
|
@ -85,7 +85,7 @@ export default {
|
|||
}
|
||||
|
||||
.auto .suggestions-container {
|
||||
@apply dark:bg-dark-400;
|
||||
@apply @dark:bg-dark-400;
|
||||
}
|
||||
|
||||
.suggestion-selected {
|
||||
|
@ -97,7 +97,7 @@ export default {
|
|||
}
|
||||
|
||||
.auto .suggestion-selected {
|
||||
@apply dark:bg-dark-100;
|
||||
@apply @dark:bg-dark-100;
|
||||
}
|
||||
|
||||
.suggestion {
|
||||
|
|
81
src/components/ShareModal.vue
Normal file
81
src/components/ShareModal.vue
Normal file
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<ModalComponent>
|
||||
<div class="flex">
|
||||
<h2 v-t="'actions.share'" />
|
||||
<button class="ml-3" @click="$emit('close')"><font-awesome-icon icon="xmark" /></button>
|
||||
</div>
|
||||
<div class="flex justify-between mt-4">
|
||||
<label v-t="'actions.with_timecode'" for="withTimeCode" />
|
||||
<input id="withTimeCode" type="checkbox" v-model="withTimeCode" />
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<label v-t="'actions.piped_link'" />
|
||||
<input type="checkbox" v-model="pipedLink" />
|
||||
</div>
|
||||
<div class="flex justify-between mt-2">
|
||||
<label v-t="'actions.time_code'" />
|
||||
<input class="input w-12" type="text" v-model="timeStamp" />
|
||||
</div>
|
||||
<h3 class="mt-4" v-text="generatedLink" />
|
||||
<div class="flex justify-end mt-4">
|
||||
<button class="btn" v-t="'actions.follow_link'" @click="followLink()" />
|
||||
<button class="btn ml-3" v-t="'actions.copy_link'" @click="copyLink()" />
|
||||
</div>
|
||||
</ModalComponent>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ModalComponent from "./ModalComponent.vue";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
videoId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
currentTime: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ModalComponent,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
withTimeCode: true,
|
||||
pipedLink: true,
|
||||
timeStamp: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.timeStamp = parseInt(this.currentTime);
|
||||
},
|
||||
methods: {
|
||||
followLink() {
|
||||
window.open(this.generatedLink, "_blank").focus();
|
||||
},
|
||||
async copyLink() {
|
||||
await this.copyURL(this.generatedLink);
|
||||
},
|
||||
async copyURL(mytext) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(mytext);
|
||||
alert(this.$t("info.copied"));
|
||||
} catch ($e) {
|
||||
alert(this.$t("info.cannot_copy"));
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
generatedLink() {
|
||||
var baseUrl = this.pipedLink
|
||||
? window.location.origin + "/watch?v=" + this.videoId
|
||||
: "https://youtu.be/" + this.videoId;
|
||||
var url = new URL(baseUrl);
|
||||
if (this.withTimeCode && this.timeStamp > 0) url.searchParams.append("t", this.timeStamp);
|
||||
return url.href;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -21,7 +21,7 @@
|
|||
<span class="mx-2" v-text="subscription.name" />
|
||||
</router-link>
|
||||
<button
|
||||
class="btn !w-min"
|
||||
class="btn w-min"
|
||||
@click="handleButton(subscription)"
|
||||
v-t="`actions.${subscription.subscribed ? 'unsubscribe' : 'subscribe'}`"
|
||||
/>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
v-text="timeFormat(video.duration)"
|
||||
/>
|
||||
<i18n-t v-else keypath="video.live" class="thumbnail-overlay thumbnail-right !bg-red-600" tag="div">
|
||||
<font-awesome-icon class="!w-3" :icon="['fas', 'broadcast-tower']" />
|
||||
<font-awesome-icon class="w-3" :icon="['fas', 'broadcast-tower']" />
|
||||
</i18n-t>
|
||||
<span v-if="video.watched" class="thumbnail-overlay bottom-5px left-5px" v-t="'video.watched'" />
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ export default {
|
|||
if (videoId)
|
||||
this.$router.replace({
|
||||
path: "/watch",
|
||||
query: { v: videoId },
|
||||
query: { v: videoId, t: this.$route.query.t },
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -47,13 +47,13 @@
|
|||
<!-- Likes/dilikes -->
|
||||
<div class="flex children:mr-2">
|
||||
<template v-if="video.likes >= 0">
|
||||
<div>
|
||||
<font-awesome-icon icon="thumbs-up" />
|
||||
<strong class="ml-2" v-text="addCommas(video.likes)" />
|
||||
<div class="flex">
|
||||
<div class="i-fa-solid:thumbs-up" />
|
||||
<strong class="ml-1" v-text="addCommas(video.likes)" />
|
||||
</div>
|
||||
<div>
|
||||
<font-awesome-icon icon="thumbs-down" />
|
||||
<strong class="ml-2" v-text="video.dislikes >= 0 ? addCommas(video.dislikes) : '?'" />
|
||||
<div class="flex">
|
||||
<div class="i-fa-solid:thumbs-down" />
|
||||
<strong class="ml-1" v-text="video.dislikes >= 0 ? addCommas(video.dislikes) : '?'" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="video.likes < 0">
|
||||
|
@ -88,6 +88,12 @@
|
|||
/>
|
||||
</div>
|
||||
<PlaylistAddModal v-if="showModal" :video-id="getVideoId()" @close="showModal = !showModal" />
|
||||
<ShareModal
|
||||
v-if="showShareModal"
|
||||
:video-id="getVideoId()"
|
||||
:current-time="currentTime"
|
||||
@close="showShareModal = !showShareModal"
|
||||
/>
|
||||
<div class="flex">
|
||||
<div class="self-center children:mr-1 my-1">
|
||||
<!-- RSS Feed button -->
|
||||
|
@ -105,15 +111,10 @@
|
|||
<font-awesome-icon icon="rss" />
|
||||
</a>
|
||||
<!-- watch on youtube button -->
|
||||
<a :href="`https://youtu.be/${getVideoId()}`" class="btn <lg:hidden">
|
||||
<i18n-t keypath="player.watch_on" tag="strong">
|
||||
<font-awesome-icon class="mx-1.5" :icon="['fab', 'youtube']" />
|
||||
</i18n-t>
|
||||
</a>
|
||||
<!-- only visible on small screens -->
|
||||
<a :href="`https://youtu.be/${getVideoId()}`" class="btn lg:hidden">
|
||||
<font-awesome-icon class="mx-1.5" :icon="['fab', 'youtube']" />
|
||||
</a>
|
||||
<button class="btn" @click="showShareModal = !showShareModal">
|
||||
<i18n-t class="lt-lg:hidden" keypath="actions.share" tag="strong"></i18n-t>
|
||||
<font-awesome-icon class="mx-1.5" icon="fa-share" />
|
||||
</button>
|
||||
<!-- LBRY -->
|
||||
<a v-if="video.lbryId" :href="'https://odysee.com/' + video.lbryId" class="btn">
|
||||
<i18n-t keypath="player.watch_on" tag="strong">LBRY</i18n-t>
|
||||
|
@ -211,6 +212,7 @@ import ErrorHandler from "./ErrorHandler.vue";
|
|||
import CommentItem from "./CommentItem.vue";
|
||||
import ChaptersBar from "./ChaptersBar.vue";
|
||||
import PlaylistAddModal from "./PlaylistAddModal.vue";
|
||||
import ShareModal from "./ShareModal.vue";
|
||||
import PlaylistVideos from "./PlaylistVideos.vue";
|
||||
|
||||
export default {
|
||||
|
@ -222,6 +224,7 @@ export default {
|
|||
CommentItem,
|
||||
ChaptersBar,
|
||||
PlaylistAddModal,
|
||||
ShareModal,
|
||||
PlaylistVideos,
|
||||
},
|
||||
data() {
|
||||
|
@ -245,6 +248,7 @@ export default {
|
|||
smallViewQuery: smallViewQuery,
|
||||
smallView: smallViewQuery.matches,
|
||||
showModal: false,
|
||||
showShareModal: false,
|
||||
isMobile: true,
|
||||
currentTime: 0,
|
||||
};
|
||||
|
@ -376,7 +380,10 @@ export default {
|
|||
|
||||
const parser = new DOMParser();
|
||||
const xmlDoc = parser.parseFromString(this.video.description, "text/html");
|
||||
xmlDoc.querySelectorAll("a").forEach(elem => (elem.outerHTML = elem.getAttribute("href")));
|
||||
xmlDoc.querySelectorAll("a").forEach(elem => {
|
||||
if (!elem.innerText.match(/(?:[\d]{1,2}:)?(?:[\d]{1,2}):(?:[\d]{1,2})/))
|
||||
elem.outerHTML = elem.getAttribute("href");
|
||||
});
|
||||
xmlDoc.querySelectorAll("br").forEach(elem => (elem.outerHTML = "\n"));
|
||||
this.video.description = this.urlify(xmlDoc.querySelector("body").innerHTML)
|
||||
.replaceAll(/(?:http(?:s)?:\/\/)?(?:www\.)?youtube\.com(\/[/a-zA-Z0-9_?=&-]*)/gm, "$1")
|
||||
|
|
|
@ -93,7 +93,11 @@
|
|||
"clone_playlist": "استنساخ قائمة التشغيل",
|
||||
"clone_playlist_success": "تم استنساخها بنجاح!",
|
||||
"download_as_txt": "تنزيل بتنسيق .txt",
|
||||
"reset_preferences": "اعادة التعيين للتفضيلات"
|
||||
"reset_preferences": "اعادة التعيين للتفضيلات",
|
||||
"confirm_reset_preferences": "هل أنت متأكد من أنك تريد إعادة تعيين تفضيلاتك؟",
|
||||
"backup_preferences": "تفضيلات النسخ الاحتياطي",
|
||||
"restore_preferences": "استعادة التفضيلات",
|
||||
"back_to_home": "العودة إلى الصفحة الرئيسية"
|
||||
},
|
||||
"video": {
|
||||
"sponsor_segments": "المقاطع الإعلانية",
|
||||
|
@ -140,5 +144,9 @@
|
|||
},
|
||||
"information": {
|
||||
"preferences_note": "ملاحظة: يتم حفظ التفضيلات في وحدة التخزين المحلية في متصفحك. سيؤدي حذف بيانات المتصفح إلى إعادة تعيينها."
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "ملاحظة: يتم حفظ التفضيلات في وحدة التخزين المحلية في متصفحك. سيؤدي حذف بيانات المتصفح إلى إعادة تعيينها.",
|
||||
"page_not_found": "لم يتم العثور على الصفحة"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
"preferences": "Seçimlər",
|
||||
"history": "Tarixçə",
|
||||
"subscriptions": "Abunəliklər",
|
||||
"playlists": "Pleylistlər"
|
||||
"playlists": "Pleylistlər",
|
||||
"account": "Hesab",
|
||||
"instance": "Server",
|
||||
"player": "Oynadıcı"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "{0} saytında baxın"
|
||||
|
@ -67,14 +70,14 @@
|
|||
"delete_playlist": "Pleylisti Silin",
|
||||
"select_playlist": "Pleylist Seçin",
|
||||
"delete_playlist_confirm": "Bu pleylist silinsin?",
|
||||
"please_select_playlist": "Lütfən, Pleylist Seçin",
|
||||
"please_select_playlist": "Lütfən, pleylist seçin",
|
||||
"country_selection": "Ölkə Seçimi",
|
||||
"default_homepage": "Defolt Əsas Səhifə",
|
||||
"show_comments": "Şərhləri Göstərin",
|
||||
"instance_selection": "Nümunə Seçimi",
|
||||
"instance_selection": "Server Seçimi",
|
||||
"minimize_description_default": "Açıqlamanı Defolt Olaraq Kiçildin",
|
||||
"language_selection": "Dil Seçimi",
|
||||
"instances_list": "Nümunələr Siyahısı",
|
||||
"instances_list": "Serverlər Siyahısı",
|
||||
"show_more": "Daha Çox Göstər",
|
||||
"no": "Xeyr",
|
||||
"store_watch_history": "Baxış Tarixçəsini Saxlayın",
|
||||
|
@ -83,10 +86,23 @@
|
|||
"show_markers": "Oynadıcıda Markerləri Göstərin",
|
||||
"delete_account": "Hesabı Silin",
|
||||
"logout": "Bu cihazdan çıxın",
|
||||
"minimize_recommendations_default": "Defolt olaraq Tövsiyələri minimuma endir"
|
||||
"minimize_recommendations_default": "Defolt olaraq Tövsiyələri minimuma endir",
|
||||
"download_as_txt": ".txt kimi endirin",
|
||||
"reset_preferences": "Seçimləri sıfırlayın",
|
||||
"confirm_reset_preferences": "Seçimləri sıfırlamaq istədiyinizə əminsiniz?",
|
||||
"backup_preferences": "Yedəkləmə seçimləri",
|
||||
"restore_preferences": "Seçimləri bərpa edin",
|
||||
"invalidate_session": "Bütün cihazlardan çıxın",
|
||||
"different_auth_instance": "Doğrulama üçün fərqli bir serverdən istifadə edin",
|
||||
"instance_auth_selection": "Autentifikasiya Server Seçimi",
|
||||
"clone_playlist": "Pleylist Klonlanması",
|
||||
"clone_playlist_success": "Uğurla klonlandı!"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Tərəfindən Sabitləndi"
|
||||
"pinned_by": "Tərəfindən Sabitləndi",
|
||||
"disabled": "Şərhlər yükləyici tərəfindən deaktiv edilib.",
|
||||
"loading": "Şərhlər yüklənir...",
|
||||
"user_disabled": "Şərhlər tənzimləmələrdə deaktiv edilib."
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "Nümunə Adı",
|
||||
|
@ -94,7 +110,7 @@
|
|||
"has_cdn": "CDN varmı?",
|
||||
"registered_users": "Qeydiyyatdan Keçmiş İstifadəçilər",
|
||||
"version": "Versiya",
|
||||
"up_to_date": "Yenilənib?",
|
||||
"up_to_date": "Güncəllənib?",
|
||||
"ssl_score": "SSL Nəticəsi"
|
||||
},
|
||||
"login": {
|
||||
|
@ -104,12 +120,12 @@
|
|||
"video": {
|
||||
"videos": "Videolar",
|
||||
"views": "{views} baxış",
|
||||
"watched": "Baxılmış",
|
||||
"watched": "Baxılıb",
|
||||
"sponsor_segments": "Sponsorlar Seqmentləri",
|
||||
"ratings_disabled": "Reytinqlər Deaktivdir",
|
||||
"chapters": "Bölümlər",
|
||||
"live": "{0} Canlı",
|
||||
"shorts": "Qısa videolar"
|
||||
"shorts": "Qısa"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Bunu nəzərdə tutursunuz: {0}?",
|
||||
|
@ -121,5 +137,11 @@
|
|||
"music_videos": "YT Music: Videolar",
|
||||
"music_albums": "YT Music: Albomlar",
|
||||
"music_playlists": "YT Music: Pleylistlər"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Abunə oldu: {0}"
|
||||
},
|
||||
"information": {
|
||||
"preferences_note": "Qeyd: seçimlər brauzerinizin yerli yaddaşında saxlanılır. Brauzer məlumatlarınızın silinməsi onları sıfırlayacaq."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,10 @@
|
|||
"clone_playlist": "Clonar Llista de Reproducció",
|
||||
"clone_playlist_success": "Clonada correctament!",
|
||||
"download_as_txt": "Descarrega com a .txt",
|
||||
"reset_preferences": "Restablir preferències"
|
||||
"reset_preferences": "Restablir preferències",
|
||||
"restore_preferences": "Restaura les preferències",
|
||||
"backup_preferences": "Preferències de la còpia de seguretat",
|
||||
"confirm_reset_preferences": "Esteu segur que voleu restablir les vostres preferències?"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Fixat per",
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
"default_homepage": "Výchozí domovská stránka",
|
||||
"show_comments": "Zobrazit komentáře",
|
||||
"minimize_description_default": "Automaticky minimalizovat popis",
|
||||
"store_watch_history": "Uložit historii sledování",
|
||||
"store_watch_history": "Ukládat historii sledování",
|
||||
"language_selection": "Výběr jazyka",
|
||||
"instances_list": "Seznam instancí",
|
||||
"enabled_codecs": "Povolené kodeky (několik)",
|
||||
|
@ -90,7 +90,11 @@
|
|||
"clone_playlist": "Duplikovat playlist",
|
||||
"clone_playlist_success": "Úspěšně duplikováno!",
|
||||
"download_as_txt": "Stáhnout jako .txt",
|
||||
"reset_preferences": "Resetovat předvolby"
|
||||
"reset_preferences": "Resetovat předvolby",
|
||||
"restore_preferences": "Obnovit předvolby",
|
||||
"backup_preferences": "Zálohovat předvolby",
|
||||
"confirm_reset_preferences": "Opravdu chcete resetovat své předvolby?",
|
||||
"back_to_home": "Zpátky domů"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Sledovat na {0}"
|
||||
|
@ -107,7 +111,7 @@
|
|||
"has_cdn": "Používá CDN?",
|
||||
"ssl_score": "Stav SSL",
|
||||
"registered_users": "Registrovaní uživatelé",
|
||||
"up_to_date": "Aktualizovaný?",
|
||||
"up_to_date": "Aktuální?",
|
||||
"version": "Verze"
|
||||
},
|
||||
"login": {
|
||||
|
@ -140,5 +144,9 @@
|
|||
},
|
||||
"information": {
|
||||
"preferences_note": "Poznámka: předvolby jsou uloženy v místním úložišti vašeho prohlížeče. Odstranění dat vašeho prohlížeče je resetuje."
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Poznámka: předvolby se ukládají do místního úložiště prohlížeče. Vymazáním dat prohlížeče budou obnoveny.",
|
||||
"page_not_found": "Stránka nenalezena"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,13 @@
|
|||
"restore_preferences": "Restore preferences",
|
||||
"back_to_home": "Back to home",
|
||||
"rename_playlist": "Rename playlist",
|
||||
"new_playlist_name": "New playlist name"
|
||||
"new_playlist_name": "New playlist name",
|
||||
"share": "Share",
|
||||
"with_timecode": "Share with time code",
|
||||
"piped_link": "Piped link",
|
||||
"follow_link": "Follow link",
|
||||
"copy_link": "Copy link",
|
||||
"time_code": "Time code (in seconds)"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Pinned by",
|
||||
|
@ -146,6 +152,8 @@
|
|||
},
|
||||
"info": {
|
||||
"preferences_note": "Note: preferences are saved in the local storage of your browser. Deleting your browser data will reset them.",
|
||||
"page_not_found": "Page not found"
|
||||
"page_not_found": "Page not found",
|
||||
"copied": "Copied!",
|
||||
"cannot_copy": "Can't copy!"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
"preferences": "Préférences",
|
||||
"history": "Historique",
|
||||
"subscriptions": "Abonnements",
|
||||
"playlists": "Listes de lecture"
|
||||
"playlists": "Listes de lecture",
|
||||
"account": "Compte",
|
||||
"instance": "Instance",
|
||||
"player": "Lecteur"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "S'abonner - {count}",
|
||||
|
@ -86,7 +89,11 @@
|
|||
"instance_auth_selection": "Sélection de l'instance d'authentification",
|
||||
"clone_playlist": "Cloner la liste de lecture",
|
||||
"clone_playlist_success": "Clonage réussi !",
|
||||
"download_as_txt": "Télécharger en tant que"
|
||||
"download_as_txt": "Télécharger en tant que",
|
||||
"reset_preferences": "Réinitialiser les préférences",
|
||||
"confirm_reset_preferences": "Êtes-vous sûre de vouloir réinitialiser les préférences ?",
|
||||
"restore_preferences": "Restaurer les préférences",
|
||||
"backup_preferences": "Sauvegarde des préférences"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Regarder sur {0}"
|
||||
|
@ -133,5 +140,8 @@
|
|||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Abonné à : {0}"
|
||||
},
|
||||
"information": {
|
||||
"preferences_note": "Note : les préférences sont sauvegardées dans le stockage local de votre navigateur. Supprimer les données de votre navigateur les réinitialiserons."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
"history": "Előzmények",
|
||||
"subscriptions": "Feliratkozások",
|
||||
"playlists": "Lejátszási listák",
|
||||
"trending": "Felkapott"
|
||||
"trending": "Felkapott",
|
||||
"account": "Fiók"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "Feliratkozás - {count}",
|
||||
|
|
|
@ -93,7 +93,10 @@
|
|||
"clone_playlist_success": "Berhasil disalin!",
|
||||
"clone_playlist": "Salin Daftar Putar",
|
||||
"download_as_txt": "Unduh sebagai .txt",
|
||||
"reset_preferences": "Atur ulang preferensi"
|
||||
"reset_preferences": "Atur ulang preferensi",
|
||||
"restore_preferences": "Pulihkan preferensi",
|
||||
"confirm_reset_preferences": "Apakah Anda yakin ingin mengatur ulang preferensi Anda?",
|
||||
"backup_preferences": "Cadangkan preferensi"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Dipasangi pin oleh",
|
||||
|
|
|
@ -76,7 +76,12 @@
|
|||
"instance_auth_selection": "Selezione dell'istanza di autenticazione",
|
||||
"clone_playlist_success": "Clonato con successo!",
|
||||
"clone_playlist": "Clona la playlist",
|
||||
"download_as_txt": "Scarica come .txt"
|
||||
"download_as_txt": "Scarica come .txt",
|
||||
"confirm_reset_preferences": "Confermi di voler reimpostare le preferenze?",
|
||||
"restore_preferences": "Ripristina le preferenze",
|
||||
"reset_preferences": "Reimposta le preferenze",
|
||||
"backup_preferences": "Salva un backup delle preferenze",
|
||||
"back_to_home": "Torna alla pagina iniziale"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Guarda su {0}"
|
||||
|
@ -89,7 +94,10 @@
|
|||
"login": "Accedi",
|
||||
"trending": "Di tendenza",
|
||||
"subscriptions": "Iscrizioni",
|
||||
"playlists": "Playlist"
|
||||
"playlists": "Playlist",
|
||||
"account": "Account",
|
||||
"instance": "Istanza",
|
||||
"player": "Riproduttore"
|
||||
},
|
||||
"video": {
|
||||
"sponsor_segments": "Segmenti sponsor",
|
||||
|
@ -133,5 +141,12 @@
|
|||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Abbonato a: {0}"
|
||||
},
|
||||
"information": {
|
||||
"preferences_note": "Nota: le preferenze sono salvate nella memoria locale del tuo browser. Se cancelli i dati del browser, le preferenze saranno ripristinate."
|
||||
},
|
||||
"info": {
|
||||
"page_not_found": "Pagina non trovata",
|
||||
"preferences_note": "Nota: le preferenze sono salvate nella memoria locale del tuo browser. L'eliminazione dei dati del tuo browser le ripristinerà."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
{
|
||||
"actions": {
|
||||
"instances_list": "Liste over instanser",
|
||||
"minimize_description_default": "Minimer beskrivelse som forvalg",
|
||||
"minimize_description_default": "Minimer beskrivelse som standard",
|
||||
"country_selection": "Land",
|
||||
"buffering_goal": "Mellomlagringsmål (i sekunder)",
|
||||
"autoplay_video": "Spill video automatisk",
|
||||
"skip_non_music": "Hopp over musikk:Del uten musikk",
|
||||
"skip_non_music": "Hopp over musikk: del uten musikk",
|
||||
"auto": "Auto",
|
||||
"skip_self_promo": "Hopp over ubetalt/selvpromotering",
|
||||
"skip_interaction": "Hopp over interaksjonspåminnelse (abonnering)",
|
||||
"skip_preview": "Hopp over forhåndsvisning/reintroduksjon",
|
||||
"skip_outro": "Skru av rulletekst/sluttpresentasjon",
|
||||
"skip_outro": "Hopp over rulletekst/utro",
|
||||
"skip_intro": "Hopp over forvideo/introanimasjon",
|
||||
"enable_sponsorblock": "Skru på sponsorblokkering",
|
||||
"language_selection": "Språk",
|
||||
"store_watch_history": "Lagre visningshistorikk",
|
||||
"show_comments": "Vis kommentarer",
|
||||
"default_homepage": "Forvalgt hjemmeside",
|
||||
"default_quality": "Forvalgt kvalitet",
|
||||
"default_homepage": "Standard hjemmeside",
|
||||
"default_quality": "Standard kvalitet",
|
||||
"audio_only": "Kun lyd",
|
||||
"light": "Lys",
|
||||
"dark": "Mørk",
|
||||
"theme": "Drakt",
|
||||
"theme": "Tema",
|
||||
"skip_sponsors": "Hopp over sponsorer",
|
||||
"uses_api_from": "Bruker API-et fra ",
|
||||
"back": "Tilbake",
|
||||
"channel_name_desc": "Kanalnavn (Å-A)",
|
||||
"channel_name_asc": "Kanalnavn (A-Å)",
|
||||
"least_recent": "Eldst",
|
||||
"most_recent": "Nyligst",
|
||||
"most_recent": "Nyest",
|
||||
"sort_by": "Sorter etter:",
|
||||
"view_subscriptions": "Vis abonnementer",
|
||||
"unsubscribe": "Opphev abonnement - {count}",
|
||||
|
@ -37,7 +37,7 @@
|
|||
"disable_lbry": "Skru av LBRY-strømming",
|
||||
"enabled_codecs": "Aktiverte forskjellige kodek",
|
||||
"show_description": "Vis beskrivelse",
|
||||
"minimize_recommendations": "Minimere anbefalinger",
|
||||
"minimize_recommendations": "Minimer anbefalinger",
|
||||
"show_recommendations": "Vis anbefalinger",
|
||||
"donations": "Donasjoner",
|
||||
"auto_play_next_video": "Autospill neste video",
|
||||
|
@ -49,7 +49,7 @@
|
|||
"show_more": "Vis mer",
|
||||
"instance_selection": "Valg av instans",
|
||||
"search": "Søk",
|
||||
"filter": "Filter",
|
||||
"filter": "Filtrer",
|
||||
"loading": "Laster inn …",
|
||||
"view_ssl_score": "Vis SSL-poengsum",
|
||||
"minimize_description": "Minimer beskrivelse",
|
||||
|
@ -60,10 +60,10 @@
|
|||
"skip_highlight": "Hopp over hovedmoment",
|
||||
"load_more_replies": "Last inn flere svar",
|
||||
"create_playlist": "Opprett spilleliste",
|
||||
"delete_playlist_confirm": "Slett denne spillelisten?",
|
||||
"delete_playlist_confirm": "Er du sikker på at du vil slette spillelisten?",
|
||||
"delete_playlist": "Slett spilleliste",
|
||||
"select_playlist": "Velg en spilleliste",
|
||||
"please_select_playlist": "Velg en spilleliste",
|
||||
"select_playlist": "Velg spilleliste",
|
||||
"please_select_playlist": "Vennligst velg en spilleliste",
|
||||
"delete_playlist_video_confirm": "Fjern video fra spilleliste?",
|
||||
"show_markers": "Vis markører i avspiller",
|
||||
"add_to_playlist": "Legg til i spilleliste",
|
||||
|
@ -78,7 +78,7 @@
|
|||
"clone_playlist": "Klon spillelisten",
|
||||
"clone_playlist_success": "Klonet",
|
||||
"reset_preferences": "Tilbakestill innstillinger",
|
||||
"backup_preferences": "Sikkerhetskopieringsinnstillinger",
|
||||
"backup_preferences": "Innstillinger for sikkerhetskopiering",
|
||||
"confirm_reset_preferences": "Tilbakestill alle innstillingene?",
|
||||
"restore_preferences": "Gjenopprett innstillinger"
|
||||
},
|
||||
|
@ -87,7 +87,7 @@
|
|||
},
|
||||
"titles": {
|
||||
"feed": "Strøm",
|
||||
"history": "HIstorikk",
|
||||
"history": "Historikk",
|
||||
"preferences": "Innstillinger",
|
||||
"register": "Registrering",
|
||||
"login": "Logg inn",
|
||||
|
@ -103,7 +103,7 @@
|
|||
"watched": "Sett",
|
||||
"views": "{views} visninger",
|
||||
"videos": "Videoer",
|
||||
"ratings_disabled": "Vurderinger avskrudd",
|
||||
"ratings_disabled": "Vurdering deaktivert",
|
||||
"chapters": "Kapitler",
|
||||
"live": "{0} direkte",
|
||||
"shorts": "Korte"
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
"register": "Registar",
|
||||
"history": "Histórico",
|
||||
"feed": "Feed",
|
||||
"playlists": "Listas de reprodução"
|
||||
"playlists": "Listas de reprodução",
|
||||
"account": "Conta",
|
||||
"instance": "Instância",
|
||||
"player": "Reprodutor"
|
||||
},
|
||||
"actions": {
|
||||
"sort_by": "Ordenar por:",
|
||||
|
@ -85,7 +88,11 @@
|
|||
"minimize_recommendations_default": "Minimizar recomendações por definição",
|
||||
"invalidate_session": "Terminar sessão em todos os dispositivos",
|
||||
"different_auth_instance": "Use uma instância diferente para autenticação",
|
||||
"instance_auth_selection": "Seleção de instância de autenticação"
|
||||
"instance_auth_selection": "Seleção de instância de autenticação",
|
||||
"confirm_reset_preferences": "Tem a certeza de que deseja restaurar as preferências originais?",
|
||||
"download_as_txt": "Descarregar como txt",
|
||||
"reset_preferences": "Repor definições originais",
|
||||
"restore_preferences": "Restaurar preferências"
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "Nome da instância",
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
"subscriptions": "Prenumerationer",
|
||||
"feed": "Flöde",
|
||||
"history": "Historik",
|
||||
"playlists": "Spellistor"
|
||||
"playlists": "Spellistor",
|
||||
"account": "Konto",
|
||||
"instance": "Instans",
|
||||
"player": "Spelare"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "Prenumerera - {count}",
|
||||
|
@ -86,7 +89,11 @@
|
|||
"invalidate_session": "Logga ut alla enheter",
|
||||
"different_auth_instance": "Använd en annan instans för autentisering",
|
||||
"instance_auth_selection": "Val av autentiseringsinstans",
|
||||
"download_as_txt": "Ladda ner som .txt"
|
||||
"download_as_txt": "Ladda ner som .txt",
|
||||
"reset_preferences": "Återställ inställningar",
|
||||
"confirm_reset_preferences": "Är du säker på att du vill återställa dina inställningar?",
|
||||
"backup_preferences": "Inställningar för säkerhetskopiering",
|
||||
"restore_preferences": "Återställa inställningar"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Titta på {0}"
|
||||
|
@ -133,5 +140,8 @@
|
|||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Prenumererar på: {0}"
|
||||
},
|
||||
"information": {
|
||||
"preferences_note": "Observera: inställningar sparas i webbläsarens lokala lagring. Om du raderar dina webbläsardata återställs de."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,8 @@
|
|||
"reset_preferences": "Tercihleri sıfırla",
|
||||
"confirm_reset_preferences": "Tercihlerinizi sıfırlamak istediğinize emin misiniz?",
|
||||
"backup_preferences": "Tercihleri yedekle",
|
||||
"restore_preferences": "Tercihleri geri yükle"
|
||||
"restore_preferences": "Tercihleri geri yükle",
|
||||
"back_to_home": "Ana sayfaya dön"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "{0} üzerinde izle"
|
||||
|
@ -143,5 +144,9 @@
|
|||
},
|
||||
"information": {
|
||||
"preferences_note": "Not: Tercihler tarayıcınızın yerel depolama alanına kaydedilir. Tarayıcı verilerinizi silmek onları sıfırlayacaktır."
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Not: Tercihler tarayıcınızın yerel depolama alanına kaydedilir. Tarayıcı verilerinizi silmek onları sıfırlayacaktır.",
|
||||
"page_not_found": "Sayfa bulunamadı"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,11 +55,12 @@
|
|||
"remove_from_playlist": "從播放清單中移除",
|
||||
"create_playlist": "建立播放清單",
|
||||
"delete_playlist": "刪除播放清單",
|
||||
"delete_playlist_confirm": "確定要刪除此播放清單嗎?",
|
||||
"delete_playlist_confirm": "要刪除這份播放清單嗎?",
|
||||
"please_select_playlist": "請選擇播放清單",
|
||||
"select_playlist": "選擇播放清單",
|
||||
"add_to_playlist": "加到播放清單",
|
||||
"delete_playlist_video_confirm": "確定要將此影片從此播放清單中移除嗎?"
|
||||
"delete_playlist_video_confirm": "要從播放清單中移除影片嗎?",
|
||||
"delete_account": "刪除帳戶"
|
||||
},
|
||||
"titles": {
|
||||
"history": "歷史記錄",
|
||||
|
@ -69,7 +70,8 @@
|
|||
"register": "註冊",
|
||||
"login": "登入",
|
||||
"subscriptions": "訂閱內容",
|
||||
"playlists": "播放清單"
|
||||
"playlists": "播放清單",
|
||||
"account": "帳戶"
|
||||
},
|
||||
"preferences": {
|
||||
"registered_users": "已註冊的使用者",
|
||||
|
@ -99,6 +101,8 @@
|
|||
"music_albums": "YT Music:專輯"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "置頂者:"
|
||||
"pinned_by": "置頂者:",
|
||||
"disabled": "上傳者停用了留言功能。",
|
||||
"loading": "留言載入中……"
|
||||
}
|
||||
}
|
||||
|
|
13
src/main.js
13
src/main.js
|
@ -1,8 +1,6 @@
|
|||
import { createApp } from "vue";
|
||||
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||
import {
|
||||
faThumbsUp,
|
||||
faThumbsDown,
|
||||
faEye,
|
||||
faThumbtack,
|
||||
faCheck,
|
||||
|
@ -18,12 +16,11 @@ import {
|
|||
faCircleMinus,
|
||||
faXmark,
|
||||
faClone,
|
||||
faShare,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { faGithub, faBitcoin, faYoutube } from "@fortawesome/free-brands-svg-icons";
|
||||
import { faGithub, faBitcoin } from "@fortawesome/free-brands-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
library.add(
|
||||
faThumbsUp,
|
||||
faThumbsDown,
|
||||
faEye,
|
||||
faGithub,
|
||||
faBitcoin,
|
||||
|
@ -31,7 +28,6 @@ library.add(
|
|||
faCheck,
|
||||
faHeart,
|
||||
faHeadphones,
|
||||
faYoutube,
|
||||
faRss,
|
||||
faChevronLeft,
|
||||
faLevelDownAlt,
|
||||
|
@ -42,6 +38,7 @@ library.add(
|
|||
faCircleMinus,
|
||||
faXmark,
|
||||
faClone,
|
||||
faShare,
|
||||
);
|
||||
|
||||
import router from "@/router/router.js";
|
||||
|
@ -57,7 +54,8 @@ TimeAgo.addDefaultLocale(en);
|
|||
|
||||
import { createI18n } from "vue-i18n";
|
||||
import enLocale from "@/locales/en.json";
|
||||
import "windi.css";
|
||||
import "@unocss/reset/tailwind.css";
|
||||
import "uno.css";
|
||||
|
||||
const timeAgo = new TimeAgo("en-US");
|
||||
|
||||
|
@ -179,6 +177,7 @@ const mixin = {
|
|||
const emailRegex = /([\w-\\.]+@(?:[\w-]+\.)+[\w-]{2,4})/g;
|
||||
return string
|
||||
.replace(urlRegex, url => {
|
||||
if (url.endsWith("</a>")) return url;
|
||||
return `<a href="${url}" target="_blank">${url}</a>`;
|
||||
})
|
||||
.replace(emailRegex, email => {
|
||||
|
|
34
uno.config.js
Normal file
34
uno.config.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { defineConfig } from "unocss";
|
||||
import transformerDirective from "@unocss/transformer-directives";
|
||||
import transformerVariantGroup from "@unocss/transformer-variant-group";
|
||||
|
||||
import presetUno from "@unocss/preset-uno";
|
||||
import presetIcons from "@unocss/preset-icons";
|
||||
import presetWebFonts from "@unocss/preset-web-fonts";
|
||||
|
||||
export default defineConfig({
|
||||
transformers: [transformerDirective(), transformerVariantGroup()],
|
||||
presets: [
|
||||
presetUno(),
|
||||
presetIcons(),
|
||||
presetWebFonts({
|
||||
provider: "none",
|
||||
fonts: {
|
||||
sans: [
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
"Segoe UI",
|
||||
"Roboto",
|
||||
"Helvetica Neue",
|
||||
"Arial",
|
||||
"Noto Sans",
|
||||
"sans-serif",
|
||||
"Apple Color Emoji",
|
||||
"Segoe UI Emoji",
|
||||
"Segoe UI Symbol",
|
||||
"Noto Color Emoji",
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
import { defineConfig } from "vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import WindiCSS from "vite-plugin-windicss";
|
||||
import Unocss from "unocss/vite";
|
||||
import legacy from "@vitejs/plugin-legacy";
|
||||
import vueI18n from "@intlify/vite-plugin-vue-i18n";
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
|
@ -11,7 +11,7 @@ import eslintPlugin from "vite-plugin-eslint";
|
|||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
WindiCSS(),
|
||||
Unocss(),
|
||||
vueI18n({
|
||||
include: path.resolve(__dirname, "./src/locales/**"),
|
||||
}),
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
module.exports = {
|
||||
darkMode: "media",
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: [
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
"Segoe UI",
|
||||
"Roboto",
|
||||
"Helvetica Neue",
|
||||
"Arial",
|
||||
"Noto Sans",
|
||||
"sans-serif",
|
||||
"Apple Color Emoji",
|
||||
"Segoe UI Emoji",
|
||||
"Segoe UI Symbol",
|
||||
"Noto Color Emoji",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
Loading…
Reference in a new issue