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

Reuse actions.okay string

This commit is contained in:
Bnyro 2023-05-31 09:50:59 +02:00
commit 0300718377
56 changed files with 1034 additions and 844 deletions

105
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,105 @@
# Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior include but are not limited to:
- The usage of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, threats, and personal or political attacks
- Harassment of any form
- Publishing others' private information, such as a physical or electronic address, without explicit permission from the individual
- Derailling conversations unnecessarily in a way that is not constructive, such as repeatedly posting off-topic comments whilest not in an off-topic channel
- Other conduct which could reasonably be considered inappropriate in a professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at the contact section of the project README, or alternatively any admin of an official medium community. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private or public, written warning from community leaders, providing
clarity when necessary around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A written warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Kick / Temporary Ban
**Community Impact**: A serious or repeated violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A kick or temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View File

@ -23,29 +23,29 @@
"stream-browserify": "3.0.0", "stream-browserify": "3.0.0",
"vue": "3.3.4", "vue": "3.3.4",
"vue-i18n": "9.2.2", "vue-i18n": "9.2.2",
"vue-router": "4.2.1", "vue-router": "4.2.2",
"xml-js": "1.6.11" "xml-js": "1.6.11"
}, },
"devDependencies": { "devDependencies": {
"@iconify-json/fa6-brands": "1.1.11", "@iconify-json/fa6-brands": "1.1.11",
"@iconify-json/fa6-solid": "1.1.13", "@iconify-json/fa6-solid": "1.1.13",
"@intlify/vite-plugin-vue-i18n": "6.0.3", "@intlify/vite-plugin-vue-i18n": "6.0.3",
"@unocss/preset-icons": "0.52.1", "@unocss/preset-icons": "0.52.5",
"@unocss/preset-web-fonts": "0.52.1", "@unocss/preset-web-fonts": "0.52.5",
"@unocss/transformer-directives": "0.52.1", "@unocss/transformer-directives": "0.52.5",
"@unocss/transformer-variant-group": "0.52.1", "@unocss/transformer-variant-group": "0.52.5",
"@vitejs/plugin-legacy": "4.0.3", "@vitejs/plugin-legacy": "4.0.4",
"@vitejs/plugin-vue": "4.2.3", "@vitejs/plugin-vue": "4.2.3",
"@vue/compiler-sfc": "3.3.4", "@vue/compiler-sfc": "3.3.4",
"eslint": "8.41.0", "eslint": "8.41.0",
"eslint-config-prettier": "8.8.0", "eslint-config-prettier": "8.8.0",
"eslint-plugin-prettier": "4.2.1", "eslint-plugin-prettier": "4.2.1",
"eslint-plugin-vue": "9.14.0", "eslint-plugin-vue": "9.14.1",
"prettier": "2.8.8", "prettier": "2.8.8",
"unocss": "0.52.1", "unocss": "0.52.5",
"vite": "4.3.8", "vite": "4.3.9",
"vite-plugin-eslint": "1.8.1", "vite-plugin-eslint": "1.8.1",
"vite-plugin-pwa": "0.15.0" "vite-plugin-pwa": "0.15.2"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,

View File

@ -216,8 +216,10 @@ b {
} }
.input:focus { .input:focus {
@apply border-2 border-red-500 outline-none; @apply outline-red-500;
box-shadow: 0 0 15px rgba(239, 68, 68, var(--un-border-opacity)); outline-style: solid;
outline-width: 2px;
box-shadow: 0 0 15px rgba(239, 68, 68, 1);
} }
hr { hr {

View File

@ -42,19 +42,7 @@
</div> </div>
</div> </div>
<!-- eslint-disable-next-line vue/no-v-html --> <CollapsableText :text="channel.description" />
<div v-if="channel.description" class="whitespace-pre-wrap py-2 mx-1">
<span v-if="fullDescription" v-html="purifyHTML(rewriteDescription(channel.description))" />
<span v-html="purifyHTML(rewriteDescription(channel.description.slice(0, 100)))" v-else />
<span v-if="channel.description.length > 100 && !fullDescription">...</span>
<button
v-if="channel.description.length > 100"
class="hover:underline font-semibold text-neutral-500 block whitespace-normal"
@click="fullDescription = !fullDescription"
>
[{{ fullDescription ? $t("actions.show_less") : $t("actions.show_more") }}]
</button>
</div>
<WatchOnYouTubeButton :link="`https://youtube.com/channel/${this.channel.id}`" /> <WatchOnYouTubeButton :link="`https://youtube.com/channel/${this.channel.id}`" />
@ -90,6 +78,7 @@ import ErrorHandler from "./ErrorHandler.vue";
import ContentItem from "./ContentItem.vue"; import ContentItem from "./ContentItem.vue";
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue"; import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue"; import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
import CollapsableText from "./CollapsableText.vue";
export default { export default {
components: { components: {
@ -97,6 +86,7 @@ export default {
ContentItem, ContentItem,
WatchOnYouTubeButton, WatchOnYouTubeButton,
LoadingIndicatorPage, LoadingIndicatorPage,
CollapsableText,
}, },
data() { data() {
return { return {
@ -105,7 +95,6 @@ export default {
tabs: [], tabs: [],
selectedTab: 0, selectedTab: 0,
contentItems: [], contentItems: [],
fullDescription: false,
}; };
}, },
mounted() { mounted() {

View File

@ -0,0 +1,28 @@
<template>
<!-- eslint-disable-next-line vue/no-v-html -->
<div v-if="text" class="whitespace-pre-wrap py-2 mx-1">
<span v-if="showFullText" v-html="purifyHTML(rewriteDescription(text))" />
<span v-else v-html="purifyHTML(rewriteDescription(text.slice(0, 100)))" />
<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"
@click="showFullText = !showFullText"
>
[{{ showFullText ? $t("actions.show_less") : $t("actions.show_more") }}]
</button>
</div>
</template>
<script>
export default {
props: {
text: String,
},
data() {
return {
showFullText: false,
};
},
};
</script>

View File

@ -4,7 +4,7 @@
<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 flex gap-2 w-min">
<button class="btn" v-t="'actions.cancel'" @click="$emit('close')" /> <button class="btn" v-t="'actions.cancel'" @click="$emit('close')" />
<button class="btn" v-t="'actions.confirm'" @click="$emit('confirm')" /> <button class="btn" v-t="'actions.okay'" @click="$emit('confirm')" />
</div> </div>
</div> </div>
</ModalComponent> </ModalComponent>

View File

@ -1,40 +1,49 @@
<template> <template>
<h1 v-t="'titles.feed'" class="font-bold text-center my-4" /> <h1 v-t="'titles.feed'" class="font-bold text-center my-4" />
<button class="btn mr-2" @click="exportHandler"> <div class="flex flex-wrap md:items-center flex-col md:flex-row gap-2 children:(flex gap-1 items-center)">
<router-link to="/subscriptions">Subscriptions</router-link> <span>
</button> <label for="filters">
<strong v-text="`${$t('actions.filter')}:`" />
</label>
<select
id="filters"
v-model="selectedFilter"
default="all"
class="select flex-grow"
@change="onFilterChange()"
>
<option v-for="filter in availableFilters" :key="filter" :value="filter" v-t="`video.${filter}`" />
</select>
</span>
<span> <span>
<a :href="getRssUrl"> <label for="group-selector">
<strong v-text="`${$t('titles.channel_groups')}:`" />
</label>
<select id="group-selector" v-model="selectedGroupName" default="" class="select flex-grow">
<option value="" v-t="`video.all`" />
<option
v-for="group in channelGroups"
:key="group.groupName"
:value="group.groupName"
v-text="group.groupName"
/>
</select>
</span>
<span class="md:ml-auto">
<SortingSelector by-key="uploaded" @apply="order => videos.sort(order)" />
</span>
</div>
<hr />
<span class="flex gap-2">
<router-link class="btn" to="/subscriptions">Subscriptions</router-link>
<a :href="getRssUrl" class="btn">
<font-awesome-icon icon="rss" /> <font-awesome-icon icon="rss" />
</a> </a>
</span> </span>
<label for="filters" class="ml-10 mr-2">
<strong v-text="`${$t('actions.filter')}:`" />
</label>
<select id="filters" v-model="selectedFilter" default="all" class="select w-auto" @change="onFilterChange()">
<option v-for="filter in availableFilters" :key="filter" :value="filter" v-t="`video.${filter}`" />
</select>
<label for="group-selector" class="ml-10 mr-2">
<strong v-text="`${$t('titles.channel_groups')}:`" />
</label>
<select id="group-selector" v-model="selectedGroupName" default="" class="select w-auto">
<option value="" v-t="`video.all`" />
<option
v-for="group in channelGroups"
:key="group.groupName"
:value="group.groupName"
v-text="group.groupName"
/>
</select>
<span class="md:float-right">
<SortingSelector by-key="uploaded" @apply="order => videos.sort(order)" />
</span>
<hr /> <hr />
<LoadingIndicatorPage :show-content="videosStore != null" class="video-grid"> <LoadingIndicatorPage :show-content="videosStore != null" class="video-grid">

View File

@ -1,14 +1,12 @@
<template> <template>
<h1 class="font-bold text-center" v-t="'titles.history'" /> <h1 class="font-bold text-center" v-t="'titles.history'" />
<div class="flex"> <div class="flex md:items-center gap-2 flex-col md:flex-row">
<div> <button class="btn" v-t="'actions.clear_history'" @click="clearHistory" />
<button class="btn" v-t="'actions.clear_history'" @click="clearHistory" />
<button class="btn mx-3" v-t="'actions.export_to_json'" @click="exportHistory" /> <button class="btn" v-t="'actions.export_to_json'" @click="exportHistory" />
</div>
<div class="right-1"> <div class="ml-auto flex gap-1 items-center">
<SortingSelector by-key="watchedAt" @apply="order => videos.sort(order)" /> <SortingSelector by-key="watchedAt" @apply="order => videos.sort(order)" />
</div> </div>
</div> </div>

View File

@ -45,13 +45,13 @@ export default {
} }
.modal-container { .modal-container {
@apply w-min m-auto px-8 bg-white p-6 rounded-xl min-w-[20vw] relative; @apply w-min m-auto bg-white p-5 rounded-xl min-w-[20vw] relative;
} }
.dark .modal-container { .dark .modal-container {
@apply bg-dark-700; @apply bg-dark-700;
} }
.modal-container > button { .modal-container > button {
@apply absolute right-8 top-6; @apply absolute right-2.5 top-1;
} }
</style> </style>

View File

@ -59,35 +59,41 @@
</ul> </ul>
</nav> </nav>
<!-- navigation bar for mobile devices --> <!-- navigation bar for mobile devices -->
<ul <div
v-if="showTopNav" v-if="showTopNav"
class="flex flex-col justify-center items-end mb-4 children:(my-0.5 mr-5)" class="mobile-nav flex flex-col mb-4 children:(p-1 w-full border-b border-dark-100 flex items-center gap-1)"
@click="showTopNav = false"
> >
<li v-if="shouldShowTrending"> <router-link v-if="shouldShowTrending" to="/trending">
<router-link v-t="'titles.trending'" to="/trending" /> <div class="i-fa6-solid:fire"></div>
</li> <i18n-t keypath="titles.trending"></i18n-t>
<li> </router-link>
<router-link v-t="'titles.preferences'" to="/preferences" /> <router-link to="/preferences">
</li> <div class="i-fa6-solid:gear"></div>
<li v-if="shouldShowLogin"> <i18n-t keypath="titles.preferences"></i18n-t>
<router-link v-t="'titles.login'" to="/login" /> </router-link>
</li> <router-link v-if="shouldShowLogin" to="/login">
<li v-if="shouldShowLogin"> <div class="i-fa6-solid:user"></div>
<router-link v-t="'titles.register'" to="/register" /> <i18n-t keypath="titles.login"></i18n-t>
</li> </router-link>
<li v-if="shouldShowHistory"> <router-link v-if="shouldShowLogin" to="/register">
<router-link v-t="'titles.history'" to="/history" /> <div class="i-fa6-solid:user-plus"></div>
</li> <i18n-t keypath="titles.register"></i18n-t>
<li> </router-link>
<router-link v-t="'titles.playlists'" to="/playlists" /> <router-link v-if="shouldShowHistory" to="/history">
</li> <div class="i-fa6-solid:clock-rotate-left"></div>
<li v-if="!shouldShowTrending"> <i18n-t keypath="titles.history"></i18n-t>
<router-link v-t="'titles.feed'" to="/feed" /> </router-link>
</li> <router-link to="/playlists">
</ul> <div class="i-fa6-solid:list"></div>
<i18n-t keypath="titles.playlists"></i18n-t>
</router-link>
<router-link v-if="!shouldShowTrending" to="/feed">
<div class="i-fa6-solid:play"></div>
<i18n-t keypath="titles.feed"></i18n-t>
</router-link>
</div>
<!-- search suggestions for mobile devices --> <!-- search suggestions for mobile devices -->
<div class="mobile-search md:hidden mx-2 search-container"> <div class="w-full mb-2 md:hidden search-container">
<input <input
v-model="searchText" v-model="searchText"
class="input h-10 w-full" class="input h-10 w-full"
@ -189,8 +195,7 @@ export default {
@apply absolute right-3 cursor-pointer rounded-full bg-[#ccc] w-4 h-4 text-center text-black opacity-50 hover:(opacity-70) text-size-[13px]; @apply absolute right-3 cursor-pointer rounded-full bg-[#ccc] w-4 h-4 text-center text-black opacity-50 hover:(opacity-70) text-size-[13px];
line-height: 1.05; line-height: 1.05;
} }
.mobile-search { .mobile-nav div {
width: calc(100% - 1rem); @apply mx-1;
@apply mx-2;
} }
</style> </style>

View File

@ -1,20 +1,21 @@
<template> <template>
<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 :show-content="playlist" v-show="!playlist.error"> <LoadingIndicatorPage :show-content="playlist" v-show="!playlist?.error">
<h1 class="text-center my-4" v-text="playlist.name" /> <h1 class="ml-1 mb-1 mt-4 text-3xl!" v-text="playlist.name" />
<div class="flex justify-between items-center"> <CollapsableText :text="playlist.description" />
<div class="flex justify-between items-center mt-1">
<div> <div>
<router-link class="link" :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" />
<strong v-text="playlist.uploader" /> <strong v-text="playlist.uploader" />
</router-link> </router-link>
</div> </div>
<div> <div>
<strong v-text="`${playlist.videos} ${$t('video.videos')}`" /> <strong v-text="`${playlist.videos} ${$t('video.videos')}`" class="mr-2" />
<br /> <button class="btn mx-1" v-if="!isPipedPlaylist" @click="bookmarkPlaylist">
<button class="btn mr-1" v-if="!isPipedPlaylist" @click="bookmarkPlaylist">
{{ $t(`actions.${isBookmarked ? "playlist_bookmarked" : "bookmark_playlist"}`) {{ $t(`actions.${isBookmarked ? "playlist_bookmarked" : "bookmark_playlist"}`)
}}<font-awesome-icon class="ml-3" icon="bookmark" /> }}<font-awesome-icon class="ml-3" icon="bookmark" />
</button> </button>
@ -52,6 +53,7 @@
<script> <script>
import ErrorHandler from "./ErrorHandler.vue"; import ErrorHandler from "./ErrorHandler.vue";
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue"; import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
import CollapsableText from "./CollapsableText.vue";
import VideoItem from "./VideoItem.vue"; import VideoItem from "./VideoItem.vue";
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue"; import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
@ -61,6 +63,7 @@ export default {
VideoItem, VideoItem,
WatchOnYouTubeButton, WatchOnYouTubeButton,
LoadingIndicatorPage, LoadingIndicatorPage,
CollapsableText,
}, },
data() { data() {
return { return {

View File

@ -39,8 +39,26 @@
v-text="playlist.name" v-text="playlist.name"
/> />
</router-link> </router-link>
<button class="btn h-auto" @click="renamePlaylist(playlist.id)" v-t="'actions.rename_playlist'" /> <button class="btn h-auto" @click="showPlaylistEditModal(playlist)" v-t="'actions.edit_playlist'" />
<button class="btn h-auto ml-2" @click="playlistToDelete = playlist.id" v-t="'actions.delete_playlist'" /> <button class="btn h-auto ml-2" @click="playlistToDelete = playlist.id" v-t="'actions.delete_playlist'" />
<ModalComponent v-if="playlist.id == playlistToEdit" @close="playlistToEdit = null">
<div class="flex flex-col gap-2">
<h2 v-t="'actions.edit_playlist'" />
<input
class="input"
type="text"
v-model="newPlaylistName"
:placeholder="$t('actions.playlist_name')"
/>
<input
class="input"
type="text"
v-model="newPlaylistDescription"
:placeholder="$t('actions.playlist_description')"
/>
<button class="btn ml-auto" @click="editPlaylist(playlist)" v-t="'actions.okay'" />
</div>
</ModalComponent>
<ConfirmModal <ConfirmModal
v-if="playlistToDelete == playlist.id" v-if="playlistToDelete == playlist.id"
:message="$t('actions.delete_playlist_confirm')" :message="$t('actions.delete_playlist_confirm')"
@ -83,6 +101,7 @@
<script> <script>
import ConfirmModal from "./ConfirmModal.vue"; import ConfirmModal from "./ConfirmModal.vue";
import ModalComponent from "./ModalComponent.vue";
export default { export default {
data() { data() {
@ -90,6 +109,9 @@ export default {
playlists: [], playlists: [],
bookmarks: [], bookmarks: [],
playlistToDelete: null, playlistToDelete: null,
playlistToEdit: null,
newPlaylistName: "",
newPlaylistDescription: "",
}; };
}, },
mounted() { mounted() {
@ -109,30 +131,48 @@ export default {
this.playlists = json; this.playlists = json;
}); });
}, },
renamePlaylist(id) { showPlaylistEditModal(playlist) {
const newName = prompt(this.$t("actions.new_playlist_name")); this.newPlaylistName = playlist.name;
if (!newName) return; this.newPlaylistDescription = playlist.description;
this.fetchJson(this.authApiUrl() + "/user/playlists/rename", null, { this.playlistToEdit = playlist.id;
method: "POST", },
body: JSON.stringify({ editPlaylist(selectedPlaylist) {
playlistId: id, // save the new name and description since they could be overwritten during the http request
newName: newName, const newName = this.newPlaylistName;
}), const newDescription = this.newPlaylistDescription;
headers: { if (newName != selectedPlaylist.name) {
Authorization: this.getAuthToken(), this.fetchJson(this.authApiUrl() + "/user/playlists/rename", null, {
"Content-Type": "application/json", method: "POST",
}, body: JSON.stringify({
}).then(json => { playlistId: selectedPlaylist.id,
if (json.error) alert(json.error); newName: newName,
else { }),
this.playlists.forEach((playlist, index) => { headers: {
if (playlist.id == id) { Authorization: this.getAuthToken(),
this.playlists[index].name = newName; "Content-Type": "application/json",
return; },
} }).then(json => {
}); if (json.error) alert(json.error);
} else selectedPlaylist.name = newName;
}); });
}
if (newDescription != selectedPlaylist.description) {
this.fetchJson(this.authApiUrl() + "/user/playlists/description", null, {
method: "PATCH",
body: JSON.stringify({
playlistId: selectedPlaylist.id,
description: newDescription,
}),
headers: {
Authorization: this.getAuthToken(),
"Content-Type": "application/json",
},
}).then(json => {
if (json.error) alert(json.error);
else selectedPlaylist.description = newDescription;
});
}
this.playlistToEdit = null;
}, },
deletePlaylist(id) { deletePlaylist(id) {
this.fetchJson(this.authApiUrl() + "/user/playlists/delete", null, { this.fetchJson(this.authApiUrl() + "/user/playlists/delete", null, {
@ -271,6 +311,6 @@ export default {
this.bookmarks.splice(index, 1); this.bookmarks.splice(index, 1);
}, },
}, },
components: { ConfirmModal }, components: { ConfirmModal, ModalComponent },
}; };
</script> </script>

View File

@ -82,7 +82,7 @@ export default {
<style> <style>
.suggestions-container { .suggestions-container {
@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; @apply left-1/2 translate-x-[-50%] transform-gpu max-w-3xl w-full box-border z-10 lt-md:max-w-[calc(100%-0.5rem)] bg-gray-300;
} }
.dark .suggestions-container { .dark .suggestions-container {
@ -98,6 +98,6 @@ export default {
} }
.suggestion { .suggestion {
@apply p-y-1; @apply p-1;
} }
</style> </style>

View File

@ -1,6 +1,6 @@
<template> <template>
<label for="ddlSortBy" v-t="'actions.sort_by'" /> <label for="ddlSortBy" v-t="'actions.sort_by'" />
<select id="ddlSortBy" v-model="selectedSort" class="select w-auto"> <select id="ddlSortBy" v-model="selectedSort" class="select flex-grow">
<option v-for="(value, key) in options" v-t="`actions.${key}`" :key="key" :value="value" /> <option v-for="(value, key) in options" v-t="`actions.${key}`" :key="key" :value="value" />
</select> </select>
</template> </template>

View File

@ -43,13 +43,13 @@
<div class="font-bold mt-2 text-2xl break-words" v-text="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="flex flex-wrap mt-3 mb-3">
<!-- views / date --> <!-- views / date -->
<div class="flex flex-auto children:ml-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) } }" />
<span> | </span> <span> | </span>
<span v-text="uploadDate" /> <span v-text="uploadDate" />
</div> </div>
<!-- Likes/dilikes --> <!-- Likes/dilikes -->
<div class="flex children:mr-2"> <div class="flex gap-2">
<template v-if="video.likes >= 0"> <template v-if="video.likes >= 0">
<div class="flex items-center"> <div class="flex items-center">
<div class="i-fa6-solid:thumbs-up" /> <div class="i-fa6-solid:thumbs-up" />
@ -68,7 +68,7 @@
</div> </div>
</div> </div>
<!-- Channel info & options flex container --> <!-- Channel info & options flex container -->
<div class="flex"> <div class="flex flex-wrap gap-1">
<!-- Channel Image & Info --> <!-- Channel Image & Info -->
<div class="flex items-center"> <div class="flex items-center">
<img :src="video.uploaderAvatar" alt="" loading="lazy" class="rounded-full" /> <img :src="video.uploaderAvatar" alt="" loading="lazy" class="rounded-full" />
@ -78,19 +78,6 @@
<!-- Verified Badge --> <!-- Verified Badge -->
<font-awesome-icon class="ml-1" v-if="video.uploaderVerified" icon="check" /> <font-awesome-icon class="ml-1" v-if="video.uploaderVerified" icon="check" />
</div> </div>
<div class="flex relative ml-auto children:mr-1 items-center">
<button class="btn" v-if="authenticated" @click="showModal = !showModal">
{{ $t("actions.add_to_playlist") }}<font-awesome-icon class="ml-1" icon="circle-plus" />
</button>
<button
class="btn"
@click="subscribeHandler"
v-t="{
path: `actions.${subscribed ? 'unsubscribe' : 'subscribe'}`,
args: { count: numberFormat(video.uploaderSubscriberCount) },
}"
/>
</div>
<PlaylistAddModal v-if="showModal" :video-id="getVideoId()" @close="showModal = !showModal" /> <PlaylistAddModal v-if="showModal" :video-id="getVideoId()" @close="showModal = !showModal" />
<ShareModal <ShareModal
v-if="showShareModal" v-if="showShareModal"
@ -100,8 +87,20 @@
:playlist-index="index" :playlist-index="index"
@close="showShareModal = !showShareModal" @close="showShareModal = !showShareModal"
/> />
<div class="flex"> <div class="flex flex-wrap gap-1 ml-auto">
<div class="self-center children:mr-1 my-1"> <!-- Subscribe Button -->
<button class="btn flex items-center" v-if="authenticated" @click="showModal = !showModal">
{{ $t("actions.add_to_playlist") }}<font-awesome-icon class="ml-1" icon="circle-plus" />
</button>
<button
class="btn"
@click="subscribeHandler"
v-t="{
path: `actions.${subscribed ? 'unsubscribe' : 'subscribe'}`,
args: { count: numberFormat(video.uploaderSubscriberCount) },
}"
/>
<div class="flex flex-wrap gap-1">
<!-- RSS Feed button --> <!-- RSS Feed button -->
<a <a
aria-label="RSS feed" aria-label="RSS feed"
@ -110,18 +109,22 @@
v-if="video.uploaderUrl" v-if="video.uploaderUrl"
:href="`${apiUrl()}/feed/unauthenticated/rss?channels=${video.uploaderUrl.split('/')[2]}`" :href="`${apiUrl()}/feed/unauthenticated/rss?channels=${video.uploaderUrl.split('/')[2]}`"
target="_blank" target="_blank"
class="btn flex-col" class="btn flex items-center"
> >
<font-awesome-icon icon="rss" /> <font-awesome-icon class="mx-1.5" icon="rss" />
</a> </a>
<WatchOnYouTubeButton :link="`https://youtu.be/${getVideoId()}`" /> <WatchOnYouTubeButton :link="`https://youtu.be/${getVideoId()}`" />
<!-- Share Dialog --> <!-- Share Dialog -->
<button class="btn" @click="showShareModal = !showShareModal"> <button class="btn flex items-center" @click="showShareModal = !showShareModal">
<i18n-t class="lt-lg:hidden" keypath="actions.share" tag="strong"></i18n-t> <i18n-t class="lt-lg:hidden" keypath="actions.share" tag="strong"></i18n-t>
<font-awesome-icon class="mx-1.5" icon="fa-share" /> <font-awesome-icon class="mx-1.5" icon="fa-share" />
</button> </button>
<!-- LBRY --> <!-- LBRY -->
<a v-if="video.lbryId" :href="'https://odysee.com/' + video.lbryId" class="btn"> <a
v-if="video.lbryId"
:href="'https://odysee.com/' + video.lbryId"
class="btn flex items-center"
>
<i18n-t keypath="player.watch_on" tag="strong">LBRY</i18n-t> <i18n-t keypath="player.watch_on" tag="strong">LBRY</i18n-t>
</a> </a>
<!-- listen / watch toggle --> <!-- listen / watch toggle -->
@ -129,9 +132,9 @@
:to="toggleListenUrl" :to="toggleListenUrl"
:aria-label="(isListening ? 'Watch ' : 'Listen to ') + video.title" :aria-label="(isListening ? 'Watch ' : 'Listen to ') + video.title"
:title="(isListening ? 'Watch ' : 'Listen to ') + video.title" :title="(isListening ? 'Watch ' : 'Listen to ') + video.title"
class="btn flex-col" class="btn flex items-center"
> >
<font-awesome-icon :icon="isListening ? 'tv' : 'headphones'" /> <font-awesome-icon class="mx-1.5" :icon="isListening ? 'tv' : 'headphones'" />
</router-link> </router-link>
</div> </div>
</div> </div>

View File

@ -107,7 +107,6 @@
"follow_link": "اتبع الرابط", "follow_link": "اتبع الرابط",
"copy_link": "نسخ الرابط", "copy_link": "نسخ الرابط",
"time_code": "رمز الوقت (بالثواني)", "time_code": "رمز الوقت (بالثواني)",
"rename_playlist": "إعادة تسمية قائمة التشغيل",
"new_playlist_name": "اسم قائمة تشغيل جديد", "new_playlist_name": "اسم قائمة تشغيل جديد",
"show_chapters": "الفصول", "show_chapters": "الفصول",
"store_search_history": "حفظ سجل البحث", "store_search_history": "حفظ سجل البحث",

View File

@ -100,7 +100,6 @@
"instance_auth_selection": "Təsdiqləmə Nümunəsi Seçimi", "instance_auth_selection": "Təsdiqləmə Nümunəsi Seçimi",
"clone_playlist": "Oynatma Siyahısın Klonla", "clone_playlist": "Oynatma Siyahısın Klonla",
"clone_playlist_success": "Uğurla klonlandı!", "clone_playlist_success": "Uğurla klonlandı!",
"rename_playlist": "Oynatma siyahısın yenidən adlandır",
"time_code": "Vaxt kodu (saniyələrlə)", "time_code": "Vaxt kodu (saniyələrlə)",
"store_search_history": "Axtarış tarixçəsini saxla", "store_search_history": "Axtarış tarixçəsini saxla",
"documentation": "Sənədləşdirmə", "documentation": "Sənədləşdirmə",

View File

@ -99,7 +99,6 @@
"clone_playlist": "Клониране на плейлист", "clone_playlist": "Клониране на плейлист",
"clone_playlist_success": "Успешно клониране!", "clone_playlist_success": "Успешно клониране!",
"backup_preferences": "Архивиране на настройките", "backup_preferences": "Архивиране на настройките",
"rename_playlist": "Преименуване на плейлиста",
"new_playlist_name": "Ново име на плейлиста", "new_playlist_name": "Ново име на плейлиста",
"back_to_home": "Обратно към начална страница", "back_to_home": "Обратно към начална страница",
"status_page": "Статус", "status_page": "Статус",

View File

@ -77,7 +77,6 @@
"minimize_chapters_default": "Smanjite poglavlja po zadanom", "minimize_chapters_default": "Smanjite poglavlja po zadanom",
"show_watch_on_youtube": "Prikaži „Gledaj na YouTube-u” dugme", "show_watch_on_youtube": "Prikaži „Gledaj na YouTube-u” dugme",
"different_auth_instance": "Koristite drugu instancu za autentifikaciju", "different_auth_instance": "Koristite drugu instancu za autentifikaciju",
"rename_playlist": "Preimenuj listu izvođenja",
"new_playlist_name": "Novi naziv liste izvođenja", "new_playlist_name": "Novi naziv liste izvođenja",
"with_timecode": "Podijelite s vremenskim kodom", "with_timecode": "Podijelite s vremenskim kodom",
"piped_link": "Piped poveznica", "piped_link": "Piped poveznica",

View File

@ -103,7 +103,6 @@
"time_code": "Moment (en segons)", "time_code": "Moment (en segons)",
"copy_link": "Copiar l'enllaç", "copy_link": "Copiar l'enllaç",
"follow_link": "Vés a l'enllaç", "follow_link": "Vés a l'enllaç",
"rename_playlist": "Canviar el nom de la llista de reproducció",
"new_playlist_name": "Nom nou de la llista de reproducció", "new_playlist_name": "Nom nou de la llista de reproducció",
"store_search_history": "Emmagatzema l'historial de cerca", "store_search_history": "Emmagatzema l'historial de cerca",
"instance_donations": "Donacions a instàncies", "instance_donations": "Donacions a instàncies",

View File

@ -104,7 +104,6 @@
"follow_link": "Otevřít odkaz", "follow_link": "Otevřít odkaz",
"copy_link": "Kopírovat odkaz", "copy_link": "Kopírovat odkaz",
"time_code": "Časový kód (v sekundách)", "time_code": "Časový kód (v sekundách)",
"rename_playlist": "Přejmenovat playlist",
"new_playlist_name": "Nový název playlistu", "new_playlist_name": "Nový název playlistu",
"show_chapters": "Kapitoly", "show_chapters": "Kapitoly",
"store_search_history": "Ukládat historii vyhledávání", "store_search_history": "Ukládat historii vyhledávání",

View File

@ -75,7 +75,6 @@
"instance_auth_selection": "Auswahl der Autentifizierungsinstanz", "instance_auth_selection": "Auswahl der Autentifizierungsinstanz",
"clone_playlist": "Playlist duplizieren", "clone_playlist": "Playlist duplizieren",
"clone_playlist_success": "Erfolgreich dupliziert!", "clone_playlist_success": "Erfolgreich dupliziert!",
"rename_playlist": "Playlist umbenennen",
"new_playlist_name": "Neuer Name der Playlist", "new_playlist_name": "Neuer Name der Playlist",
"piped_link": "Piped-Link", "piped_link": "Piped-Link",
"download_as_txt": "Als .txt herunterladen", "download_as_txt": "Als .txt herunterladen",

View File

@ -111,7 +111,9 @@
"backup_preferences": "Backup preferences", "backup_preferences": "Backup preferences",
"restore_preferences": "Restore preferences", "restore_preferences": "Restore preferences",
"back_to_home": "Back to home", "back_to_home": "Back to home",
"rename_playlist": "Rename playlist", "edit_playlist": "Edit playlist",
"playlist_name": "Playlist name",
"playlist_description": "Playlist description",
"new_playlist_name": "New playlist name", "new_playlist_name": "New playlist name",
"share": "Share", "share": "Share",
"with_timecode": "Share with time code", "with_timecode": "Share with time code",
@ -137,7 +139,7 @@
"create_group": "Create group", "create_group": "Create group",
"group_name": "Group name", "group_name": "Group name",
"cancel": "Cancel", "cancel": "Cancel",
"confirm": "Confirm" "okay": "Okay"
}, },
"comment": { "comment": {
"pinned_by": "Pinned by {author}", "pinned_by": "Pinned by {author}",

View File

@ -55,7 +55,6 @@
"hide_replies": "Kaŝi Respondojn", "hide_replies": "Kaŝi Respondojn",
"add_to_playlist": "Aldoni al ludlisto", "add_to_playlist": "Aldoni al ludlisto",
"delete_playlist": "Forigi Ludliston", "delete_playlist": "Forigi Ludliston",
"rename_playlist": "Renomi ludliston",
"download_as_txt": "Elŝuti kiel .txt", "download_as_txt": "Elŝuti kiel .txt",
"piped_link": "Piped-ligilo", "piped_link": "Piped-ligilo",
"copy_link": "Kopii ligilon", "copy_link": "Kopii ligilon",

View File

@ -103,7 +103,6 @@
"invalidate_session": "Cerrar sesión en todos los dispositivos", "invalidate_session": "Cerrar sesión en todos los dispositivos",
"instance_auth_selection": "Selección de la Instancia de Autentificación", "instance_auth_selection": "Selección de la Instancia de Autentificación",
"download_as_txt": "Descargar como .txt", "download_as_txt": "Descargar como .txt",
"rename_playlist": "Cambiar el nombre de la lista de reproducción",
"new_playlist_name": "Nuevo nombre de la lista de reproducción", "new_playlist_name": "Nuevo nombre de la lista de reproducción",
"share": "Compartir", "share": "Compartir",
"with_timecode": "Compartir con código de tiempo", "with_timecode": "Compartir con código de tiempo",

View File

@ -101,7 +101,6 @@
"show_watch_on_youtube": "Näytä Katso YouTubessa -painike", "show_watch_on_youtube": "Näytä Katso YouTubessa -painike",
"different_auth_instance": "Käytä eri instanssia todennukseen", "different_auth_instance": "Käytä eri instanssia todennukseen",
"download_as_txt": "Lataa .txt-tiedostona", "download_as_txt": "Lataa .txt-tiedostona",
"rename_playlist": "Nimeä soittolista uudelleen",
"show_chapters": "Luvut", "show_chapters": "Luvut",
"minimize_comments": "Minimoi kommentit", "minimize_comments": "Minimoi kommentit",
"minimize_comments_default": "Minimoi kommentit oletusarvoisesti", "minimize_comments_default": "Minimoi kommentit oletusarvoisesti",

View File

@ -103,7 +103,6 @@
"piped_link": "Lien vers Piped", "piped_link": "Lien vers Piped",
"follow_link": "Ouvrir le lien", "follow_link": "Ouvrir le lien",
"time_code": "Horodatage (en secondes)", "time_code": "Horodatage (en secondes)",
"rename_playlist": "Renommer la liste de lecture",
"new_playlist_name": "Nouveau nom de la liste de lecture", "new_playlist_name": "Nouveau nom de la liste de lecture",
"show_chapters": "Chapitres", "show_chapters": "Chapitres",
"store_search_history": "Mémoriser l'historique de recherche", "store_search_history": "Mémoriser l'historique de recherche",

View File

@ -104,7 +104,6 @@
"search": "חיפוש (Ctrl+K)", "search": "חיפוש (Ctrl+K)",
"loop_this_video": "ניגון הסרטון בלולאה", "loop_this_video": "ניגון הסרטון בלולאה",
"minimize_recommendations": "מזעור המלצות", "minimize_recommendations": "מזעור המלצות",
"rename_playlist": "שינוי שם רשימת נגינה",
"new_playlist_name": "שם לרשימת נגינה חדשה", "new_playlist_name": "שם לרשימת נגינה חדשה",
"show_chapters": "פרקים", "show_chapters": "פרקים",
"skip_intro": "דילוג על הפוגה/הנפשת הקדמה", "skip_intro": "דילוג על הפוגה/הנפשת הקדמה",

View File

@ -113,7 +113,6 @@
"confirm_reset_preferences": "Stvarno želiš resetirati tvoje postavke?", "confirm_reset_preferences": "Stvarno želiš resetirati tvoje postavke?",
"backup_preferences": "Spremi sigurnosnu kopiju postavki", "backup_preferences": "Spremi sigurnosnu kopiju postavki",
"with_timecode": "Dijeli s vremenskim kodom", "with_timecode": "Dijeli s vremenskim kodom",
"rename_playlist": "Preimenuj popis snimaka",
"new_playlist_name": "Ime novog popisa snimaka", "new_playlist_name": "Ime novog popisa snimaka",
"share": "Dijeli", "share": "Dijeli",
"show_chapters": "Poglavlja", "show_chapters": "Poglavlja",
@ -140,7 +139,8 @@
"autoplay_next_countdown": "Standardno odbrojavanje do sljedećeg videa (u sekundama)", "autoplay_next_countdown": "Standardno odbrojavanje do sljedećeg videa (u sekundama)",
"dismiss": "Odbaci", "dismiss": "Odbaci",
"create_group": "Stvori grupu", "create_group": "Stvori grupu",
"group_name": "Ime grupe" "group_name": "Ime grupe",
"auto_display_captions": "Automatski prikaži titlove"
}, },
"player": { "player": {
"watch_on": "Gledaj na {0}" "watch_on": "Gledaj na {0}"

View File

@ -92,7 +92,6 @@
"clone_playlist_success": "Sikeresen klónozva!", "clone_playlist_success": "Sikeresen klónozva!",
"reset_preferences": "Alaphelyzetbe állítás", "reset_preferences": "Alaphelyzetbe állítás",
"restore_preferences": "Beállítások betöltése fájlból", "restore_preferences": "Beállítások betöltése fájlból",
"rename_playlist": "Átnevez",
"instance_donations": "Szerver adományozások", "instance_donations": "Szerver adományozások",
"piped_link": "Piped link", "piped_link": "Piped link",
"time_code": "Idő kód (másodpercekben)", "time_code": "Idő kód (másodpercekben)",

View File

@ -76,7 +76,6 @@
"confirm_reset_preferences": "Իսկապե՞ս ուզում եք վերակայել ձեր նախապատվությունները:", "confirm_reset_preferences": "Իսկապե՞ս ուզում եք վերակայել ձեր նախապատվությունները:",
"backup_preferences": "Պահուստային նախապատվություններ", "backup_preferences": "Պահուստային նախապատվություններ",
"restore_preferences": "Վերականգնել նախապատվությունները", "restore_preferences": "Վերականգնել նախապատվությունները",
"rename_playlist": "Վերանվանել տեսացանկը",
"new_playlist_name": "Տեսացանկի նոր անվանում", "new_playlist_name": "Տեսացանկի նոր անվանում",
"follow_link": "Հետևել հղմանը", "follow_link": "Հետևել հղմանը",
"instance_donations": "Օրինակների նվիրատվություններ", "instance_donations": "Օրինակների նվիրատվություններ",

View File

@ -100,7 +100,6 @@
"restore_preferences": "Pulihkan preferensi", "restore_preferences": "Pulihkan preferensi",
"confirm_reset_preferences": "Apakah Anda yakin ingin mengatur ulang preferensi Anda?", "confirm_reset_preferences": "Apakah Anda yakin ingin mengatur ulang preferensi Anda?",
"backup_preferences": "Cadangkan preferensi", "backup_preferences": "Cadangkan preferensi",
"rename_playlist": "Ubah nama daftar putar",
"new_playlist_name": "Nama daftar putar baru", "new_playlist_name": "Nama daftar putar baru",
"share": "Bagikan", "share": "Bagikan",
"with_timecode": "Bagikan dengan kode waktu", "with_timecode": "Bagikan dengan kode waktu",

View File

@ -12,7 +12,9 @@
"account": "Reikningur", "account": "Reikningur",
"instance": "Tilvik", "instance": "Tilvik",
"livestreams": "Útsendingar í beinni", "livestreams": "Útsendingar í beinni",
"channels": "Rásir" "channels": "Rásir",
"bookmarks": "Bókamerki",
"channel_groups": "Rásarhópar"
}, },
"actions": { "actions": {
"sort_by": "Raða eftir:", "sort_by": "Raða eftir:",
@ -94,7 +96,6 @@
"instance_donations": "Framlög til netþjóns", "instance_donations": "Framlög til netþjóns",
"status_page": "Staða", "status_page": "Staða",
"source_code": "Frumkóði", "source_code": "Frumkóði",
"rename_playlist": "Endurnefna spilunarlista",
"new_playlist_name": "Nýtt heiti spilunarlista", "new_playlist_name": "Nýtt heiti spilunarlista",
"share": "Deila", "share": "Deila",
"with_timecode": "Deilа með tímakóða", "with_timecode": "Deilа með tímakóða",

View File

@ -88,7 +88,6 @@
"follow_link": "Apri il collegamento", "follow_link": "Apri il collegamento",
"with_timecode": "Condividi con marca temporale", "with_timecode": "Condividi con marca temporale",
"new_playlist_name": "Nuovo nome dalla playlist", "new_playlist_name": "Nuovo nome dalla playlist",
"rename_playlist": "Rinomina la playlist",
"show_chapters": "Capitoli", "show_chapters": "Capitoli",
"store_search_history": "Memorizza la cronologia delle ricerche", "store_search_history": "Memorizza la cronologia delle ricerche",
"status_page": "Stato", "status_page": "Stato",

View File

@ -17,7 +17,7 @@
"channel_groups": "グループ" "channel_groups": "グループ"
}, },
"player": { "player": {
"watch_on": "{0}で視聴" "watch_on": "{0}で視聴"
}, },
"actions": { "actions": {
"subscribe": "チャンネル登録 - {count}", "subscribe": "チャンネル登録 - {count}",
@ -29,13 +29,13 @@
"channel_name_asc": "チャンネル名 (AからZ)", "channel_name_asc": "チャンネル名 (AからZ)",
"channel_name_desc": "チャンネル名 (ZからA)", "channel_name_desc": "チャンネル名 (ZからA)",
"back": "戻る", "back": "戻る",
"uses_api_from": "API使用元 ", "uses_api_from": "API 提供元 ",
"enable_sponsorblock": "SponsorBlock を有効化", "enable_sponsorblock": "SponsorBlock を有効化",
"skip_sponsors": "広告をスキップ", "skip_sponsors": "広告をスキップ",
"skip_intro": "休止時間/導入アニメをスキップ", "skip_intro": "休止時間/導入アニメをスキップ",
"skip_outro": "終了シーン/クレジットをスキップ", "skip_outro": "終了シーン/クレジットをスキップ",
"skip_preview": "プレビュー/要約をスキップ", "skip_preview": "プレビュー/要約をスキップ",
"skip_interaction": "チャンネル登録など操作を求める自己宣伝をスキップ", "skip_interaction": "登録など操作を頼む自己宣伝をスキップ",
"skip_self_promo": "無報酬/自己の宣伝をスキップ", "skip_self_promo": "無報酬/自己の宣伝をスキップ",
"skip_non_music": "音楽: 非音楽部分をスキップ", "skip_non_music": "音楽: 非音楽部分をスキップ",
"theme": "テーマ", "theme": "テーマ",
@ -43,14 +43,14 @@
"dark": "ダーク", "dark": "ダーク",
"light": "ライト", "light": "ライト",
"autoplay_video": "動画を自動再生", "autoplay_video": "動画を自動再生",
"audio_only": "音声のみ", "audio_only": "音声のみのモード",
"default_quality": "標準の画質", "default_quality": "標準の画質",
"buffering_goal": "バッファリング目標値 (秒)", "buffering_goal": "バッファリング目標値 (秒)",
"country_selection": "国の選択", "country_selection": "国の選択",
"default_homepage": "ホームに表示するページ", "default_homepage": "ホームに表示するページ",
"show_comments": "コメントを表示", "show_comments": "コメントを表示",
"minimize_description_default": "最初から説明を最小化", "minimize_description_default": "最初から説明を最小化",
"store_watch_history": "再生履歴を保存する", "store_watch_history": "再生履歴を保存",
"language_selection": "言語の選択", "language_selection": "言語の選択",
"instances_list": "インスタンス一覧", "instances_list": "インスタンス一覧",
"enabled_codecs": "コーデックの有効化 (複数選択)", "enabled_codecs": "コーデックの有効化 (複数選択)",
@ -68,7 +68,7 @@
"minimize_recommendations": "おすすめを最小化", "minimize_recommendations": "おすすめを最小化",
"show_recommendations": "おすすめを見る", "show_recommendations": "おすすめを見る",
"disable_lbry": "ストリーミングのLBRYを無効化", "disable_lbry": "ストリーミングのLBRYを無効化",
"enable_lbry_proxy": "LBRYプロキシをオン", "enable_lbry_proxy": "LBRYにプロキシを使用",
"view_ssl_score": "SSLの評価を表示", "view_ssl_score": "SSLの評価を表示",
"search": "検索 (Ctrl+K)", "search": "検索 (Ctrl+K)",
"filter": "フィルター", "filter": "フィルター",
@ -87,8 +87,8 @@
"show_markers": "プレイヤーに目印の区切りを表示", "show_markers": "プレイヤーに目印の区切りを表示",
"select_playlist": "再生リストを選択", "select_playlist": "再生リストを選択",
"delete_playlist_confirm": "再生リストを削除しますか?", "delete_playlist_confirm": "再生リストを削除しますか?",
"delete_account": "アカウントを削除する", "delete_account": "アカウントを削除",
"store_search_history": "検索履歴を保存する", "store_search_history": "検索履歴を保存",
"show_chapters": "チャプター", "show_chapters": "チャプター",
"status_page": "状態", "status_page": "状態",
"source_code": "ソースコード", "source_code": "ソースコード",
@ -96,15 +96,15 @@
"minimize_comments": "コメントを最小化", "minimize_comments": "コメントを最小化",
"share": "共有", "share": "共有",
"with_timecode": "時間指定で共有", "with_timecode": "時間指定で共有",
"different_auth_instance": "認証に別のインスタンスを使う", "different_auth_instance": "認証に別のインスタンスを使う",
"download_as_txt": ".txtでダウンロード", "download_as_txt": ".txtでダウンロード",
"logout": "このデバイスでログアウト", "logout": "この端末からログアウト",
"minimize_recommendations_default": "最初からおすすめを最小化", "minimize_recommendations_default": "最初からおすすめを最小化",
"hide_watched": "再生済みの動画をフィードに表示しない", "hide_watched": "再生済みの動画をフィードに表示しない",
"minimize_chapters_default": "最初からチャプターを最小化", "minimize_chapters_default": "最初からチャプターを最小化",
"show_watch_on_youtube": "「YouTubeで見る」ボタンを表示する", "show_watch_on_youtube": "「YouTubeで視聴」ボタンを表示",
"invalidate_session": "すべてのデバイスでログアウトする", "invalidate_session": "すべての端末からログアウト",
"instance_auth_selection": "認証インスタンスの選択", "instance_auth_selection": "認証インスタンスの選択",
"clone_playlist_success": "複製に成功しました!", "clone_playlist_success": "複製に成功しました!",
"backup_preferences": "設定をバックアップ", "backup_preferences": "設定をバックアップ",
"restore_preferences": "設定を復元", "restore_preferences": "設定を復元",
@ -114,7 +114,6 @@
"documentation": "ドキュメント", "documentation": "ドキュメント",
"reset_preferences": "設定を初期化", "reset_preferences": "設定を初期化",
"confirm_reset_preferences": "設定をリセットしますか?", "confirm_reset_preferences": "設定をリセットしますか?",
"rename_playlist": "再生リスト名を変更する",
"piped_link": "Pipedリンク", "piped_link": "Pipedリンク",
"new_playlist_name": "新しい再生リスト名", "new_playlist_name": "新しい再生リスト名",
"follow_link": "リンクを開く", "follow_link": "リンクを開く",
@ -147,7 +146,7 @@
"instance_locations": "インスタンスの場所", "instance_locations": "インスタンスの場所",
"has_cdn": "CDNの有無", "has_cdn": "CDNの有無",
"ssl_score": "SSLの評価", "ssl_score": "SSLの評価",
"registered_users": "登録ユーザー数", "registered_users": "登録利用者数",
"version": "バージョン", "version": "バージョン",
"up_to_date": "最新?" "up_to_date": "最新?"
}, },
@ -184,8 +183,8 @@
"cannot_copy": "コピーできません!", "cannot_copy": "コピーできません!",
"preferences_note": "注意: 設定は、お使いのブラウザの保存領域に保存されます。ブラウザのデータを削除すると初期化されます。", "preferences_note": "注意: 設定は、お使いのブラウザの保存領域に保存されます。ブラウザのデータを削除すると初期化されます。",
"local_storage": "この操作にはlocalStorageが必要です。Cookieは有効ですか", "local_storage": "この操作にはlocalStorageが必要です。Cookieは有効ですか",
"register_no_email_note": "Eメールアドレスをユーザー名として使用することは推奨されていません。それでも続行しますか?", "register_no_email_note": "ユーザー名としてのメールアドレスの使用は推奨しません。それでも続けますか?",
"next_video_countdown": "{0} 秒後に次の動画を再生" "next_video_countdown": "{0} 秒後に次の動画"
}, },
"subscriptions": { "subscriptions": {
"subscribed_channels_count": "チャンネル登録: {0}" "subscribed_channels_count": "チャンネル登録: {0}"

View File

@ -98,7 +98,6 @@
"backup_preferences": "Ḥrez ismenyifen", "backup_preferences": "Ḥrez ismenyifen",
"restore_preferences": "Err-d ismenyifen", "restore_preferences": "Err-d ismenyifen",
"back_to_home": "Uɣal ɣer ugejdan", "back_to_home": "Uɣal ɣer ugejdan",
"rename_playlist": "Beddel isem i tebdart n tɣuri",
"follow_link": "Ḍfer aseɣwen", "follow_link": "Ḍfer aseɣwen",
"show_chapters": "Ixfawen", "show_chapters": "Ixfawen",
"show_watch_on_youtube": "Sken taqeffalt Wali ɣef YouTube", "show_watch_on_youtube": "Sken taqeffalt Wali ɣef YouTube",

View File

@ -70,7 +70,6 @@
"show_chapters": "챕터", "show_chapters": "챕터",
"download_as_txt": ".txt로 다운로드", "download_as_txt": ".txt로 다운로드",
"new_playlist_name": "새 재생목록 이름", "new_playlist_name": "새 재생목록 이름",
"rename_playlist": "재생목록 이름 변경",
"share": "공유", "share": "공유",
"copy_link": "링크 복사", "copy_link": "링크 복사",
"time_code": "시작 시간 (초)", "time_code": "시작 시간 (초)",

View File

@ -80,7 +80,6 @@
"reply_count": "{count} atsakymai", "reply_count": "{count} atsakymai",
"show_chapters": "Skirsniai", "show_chapters": "Skirsniai",
"piped_link": "Piped nuoroda", "piped_link": "Piped nuoroda",
"rename_playlist": "Pervardyti grojaraštį",
"follow_link": "Sekti nuorodą", "follow_link": "Sekti nuorodą",
"store_search_history": "Išsaugoti paieškos istoriją", "store_search_history": "Išsaugoti paieškos istoriją",
"hide_watched": "Slėpti žiūrėtus vaizdo įrašus sklaidos kanale", "hide_watched": "Slėpti žiūrėtus vaizdo įrašus sklaidos kanale",

View File

@ -81,7 +81,6 @@
"confirm_reset_preferences": "Tilbakestill alle innstillingene?", "confirm_reset_preferences": "Tilbakestill alle innstillingene?",
"restore_preferences": "Gjenopprett innstillinger", "restore_preferences": "Gjenopprett innstillinger",
"show_chapters": "Kapitler", "show_chapters": "Kapitler",
"rename_playlist": "Gi spillelisten ny navn",
"new_playlist_name": "Nytt spillelistenavn", "new_playlist_name": "Nytt spillelistenavn",
"share": "Del", "share": "Del",
"with_timecode": "Del med tidskode", "with_timecode": "Del med tidskode",

View File

@ -80,7 +80,6 @@
"instance_auth_selection": "Selectie authenticatie-instantie", "instance_auth_selection": "Selectie authenticatie-instantie",
"clone_playlist": "Afspeellijst dupliceren", "clone_playlist": "Afspeellijst dupliceren",
"download_as_txt": "Downloaden als .txt", "download_as_txt": "Downloaden als .txt",
"rename_playlist": "Afspeellijst hernoemen",
"new_playlist_name": "Nieuwe afspeellijstnaam", "new_playlist_name": "Nieuwe afspeellijstnaam",
"share": "Delen", "share": "Delen",
"documentation": "Documentatie", "documentation": "Documentatie",

View File

@ -98,7 +98,6 @@
"invalidate_session": "Se desconnectar de totes los aparelhs", "invalidate_session": "Se desconnectar de totes los aparelhs",
"different_auth_instance": "Utilizar una instància diferenta per lautentificacion", "different_auth_instance": "Utilizar una instància diferenta per lautentificacion",
"back_to_home": "Tornar a lacuèlh", "back_to_home": "Tornar a lacuèlh",
"rename_playlist": "Renomenar la lista de lectura",
"new_playlist_name": "Nom novèl de la lista de lectura", "new_playlist_name": "Nom novèl de la lista de lectura",
"with_timecode": "Partejar amb còdi orari", "with_timecode": "Partejar amb còdi orari",
"piped_link": "Ligam cap a Piped", "piped_link": "Ligam cap a Piped",

View File

@ -35,7 +35,6 @@
"show_recommendations": "ସୁପାରିଶଗୁଡିକ ଦେଖାନ୍ତୁ", "show_recommendations": "ସୁପାରିଶଗୁଡିକ ଦେଖାନ୍ତୁ",
"disable_lbry": "ଷ୍ଟ୍ରିମିଂ ପାଇଁ LBRY ଅକ୍ଷମ କରନ୍ତୁ", "disable_lbry": "ଷ୍ଟ୍ରିମିଂ ପାଇଁ LBRY ଅକ୍ଷମ କରନ୍ତୁ",
"search": "ସନ୍ଧାନ କରନ୍ତୁ (Ctrl+K)", "search": "ସନ୍ଧାନ କରନ୍ତୁ (Ctrl+K)",
"rename_playlist": "ପ୍ଲେ ଲିଷ୍ଟର ନାମ ପରିବର୍ତ୍ତନ କରନ୍ତୁ",
"new_playlist_name": "ନୂତନ ପ୍ଲେଲିଷ୍ଟ ନାମ", "new_playlist_name": "ନୂତନ ପ୍ଲେଲିଷ୍ଟ ନାମ",
"channel_name_asc": "ସ୍ରୋତ ର ନାମ (A-Z)", "channel_name_asc": "ସ୍ରୋତ ର ନାମ (A-Z)",
"least_recent": "ସର୍ବନିମ୍ନ ସାମ୍ପ୍ରତିକ", "least_recent": "ସର୍ବନିମ୍ନ ସାମ୍ପ୍ରତିକ",

View File

@ -102,7 +102,6 @@
"source_code": "Kod źródłowy", "source_code": "Kod źródłowy",
"show_chapters": "Rozdziały", "show_chapters": "Rozdziały",
"minimize_chapters_default": "Ukryj rozdziały", "minimize_chapters_default": "Ukryj rozdziały",
"rename_playlist": "Zmień nazwę playlisty",
"follow_link": "Otwórz link", "follow_link": "Otwórz link",
"minimize_comments_default": "Ukryj sekcję komentarzy", "minimize_comments_default": "Ukryj sekcję komentarzy",
"minimize_comments": "Ukryj komentarze", "minimize_comments": "Ukryj komentarze",

View File

@ -110,7 +110,6 @@
"new_playlist_name": "Novo nome da lista de reprodução", "new_playlist_name": "Novo nome da lista de reprodução",
"minimize_comments": "Minimizar Comentários", "minimize_comments": "Minimizar Comentários",
"back_to_home": "Voltar ao início", "back_to_home": "Voltar ao início",
"rename_playlist": "Renomear",
"copy_link": "Copiar ligação", "copy_link": "Copiar ligação",
"time_code": "Código de tempo (em segundos)", "time_code": "Código de tempo (em segundos)",
"minimize_comments_default": "Minimizar Comentários por defeito", "minimize_comments_default": "Minimizar Comentários por defeito",
@ -130,7 +129,8 @@
"dismiss": "Ignorar", "dismiss": "Ignorar",
"autoplay_next_countdown": "Predefinição Contagem decrescente até ao próximo vídeo (em segundos)", "autoplay_next_countdown": "Predefinição Contagem decrescente até ao próximo vídeo (em segundos)",
"create_group": "Criar grupo", "create_group": "Criar grupo",
"group_name": "Nome do grupo" "group_name": "Nome do grupo",
"auto_display_captions": "Visualização automática de legendas"
}, },
"preferences": { "preferences": {
"instance_name": "Nome da Instância", "instance_name": "Nome da Instância",

View File

@ -87,7 +87,6 @@
"restore_preferences": "Restaurar preferências", "restore_preferences": "Restaurar preferências",
"back_to_home": "Voltar ao início", "back_to_home": "Voltar ao início",
"share": "Compartilhar", "share": "Compartilhar",
"rename_playlist": "Renomear playlist",
"new_playlist_name": "Novo nome da playlist", "new_playlist_name": "Novo nome da playlist",
"with_timecode": "Compartilhar com código de tempo", "with_timecode": "Compartilhar com código de tempo",
"piped_link": "Link do Piped", "piped_link": "Link do Piped",

View File

@ -93,7 +93,6 @@
"invalidate_session": "Terminar sessão em todos os aparelhos", "invalidate_session": "Terminar sessão em todos os aparelhos",
"clone_playlist": "Clonar Lista de Reprodução", "clone_playlist": "Clonar Lista de Reprodução",
"clone_playlist_success": "Clonada com sucesso!", "clone_playlist_success": "Clonada com sucesso!",
"rename_playlist": "Renomear",
"restore_preferences": "Restaurar configurações", "restore_preferences": "Restaurar configurações",
"confirm_reset_preferences": "Tem a certeza que quer redefinir as suas configurações?", "confirm_reset_preferences": "Tem a certeza que quer redefinir as suas configurações?",
"new_playlist_name": "Novo nome da lista de reprodução", "new_playlist_name": "Novo nome da lista de reprodução",
@ -130,7 +129,8 @@
"autoplay_next_countdown": "Predefinição Contagem decrescente até ao próximo vídeo (em segundos)", "autoplay_next_countdown": "Predefinição Contagem decrescente até ao próximo vídeo (em segundos)",
"dismiss": "Ignorar", "dismiss": "Ignorar",
"create_group": "Criar grupo", "create_group": "Criar grupo",
"group_name": "Nome do grupo" "group_name": "Nome do grupo",
"auto_display_captions": "Visualização automática de legendas"
}, },
"comment": { "comment": {
"pinned_by": "Afixado por {author}", "pinned_by": "Afixado por {author}",

View File

@ -59,7 +59,6 @@
"clone_playlist_success": "Clonată cu succes!", "clone_playlist_success": "Clonată cu succes!",
"reset_preferences": "Resetați preferințele", "reset_preferences": "Resetați preferințele",
"confirm_reset_preferences": "Sunteți sigur că doriți să vă resetați preferințele?", "confirm_reset_preferences": "Sunteți sigur că doriți să vă resetați preferințele?",
"rename_playlist": "Redenumiți playlist-ul",
"new_playlist_name": "Numele playlist-ului nou", "new_playlist_name": "Numele playlist-ului nou",
"share": "Distribuiți", "share": "Distribuiți",
"follow_link": "Urmați link-ul", "follow_link": "Urmați link-ul",

View File

@ -97,7 +97,6 @@
"clone_playlist": "Клонировать плейлист", "clone_playlist": "Клонировать плейлист",
"clone_playlist_success": "Успешно клонировано!", "clone_playlist_success": "Успешно клонировано!",
"show_chapters": "Главы", "show_chapters": "Главы",
"rename_playlist": "Переименовать плейлист",
"new_playlist_name": "Новое название плейлиста", "new_playlist_name": "Новое название плейлиста",
"share": "Поделиться", "share": "Поделиться",
"with_timecode": "Поделиться с таймкодом", "with_timecode": "Поделиться с таймкодом",

View File

@ -81,7 +81,6 @@
"backup_preferences": "සැකසුම් උපස්ථ කරන්න", "backup_preferences": "සැකසුම් උපස්ථ කරන්න",
"restore_preferences": "සැකසුම් නැවත පිහිටුවන්න", "restore_preferences": "සැකසුම් නැවත පිහිටුවන්න",
"back_to_home": "ආපසු මුල් පිටුවට", "back_to_home": "ආපසු මුල් පිටුවට",
"rename_playlist": "වාදන ලැයිස්තුව නැවත නම් කරන්න",
"share": "බෙදාගන්න", "share": "බෙදාගන්න",
"with_timecode": "කාල කේතය සමඟ බෙදා ගන්න", "with_timecode": "කාල කේතය සමඟ බෙදා ගන්න",
"piped_link": "පයිප්ඩ් සබැඳිය", "piped_link": "පයිප්ඩ් සබැඳිය",

View File

@ -72,7 +72,6 @@
"view_ssl_score": "Zobraziť SSL skóre", "view_ssl_score": "Zobraziť SSL skóre",
"filter": "Filter", "filter": "Filter",
"delete_playlist_video_confirm": "Odstrániť video zo zoznamu?", "delete_playlist_video_confirm": "Odstrániť video zo zoznamu?",
"rename_playlist": "Premenovať zoznam skladieb",
"new_playlist_name": "Nový názov zoznamu skladieb", "new_playlist_name": "Nový názov zoznamu skladieb",
"share": "Zdieľať", "share": "Zdieľať",
"follow_link": "Nasledujte odkaz", "follow_link": "Nasledujte odkaz",

View File

@ -100,7 +100,6 @@
"status_page": "Статус", "status_page": "Статус",
"instance_donations": "Донације инстанци", "instance_donations": "Донације инстанци",
"show_chapters": "Поглавља", "show_chapters": "Поглавља",
"rename_playlist": "Преименуј плејлисту",
"with_timecode": "Подели са временским кодом", "with_timecode": "Подели са временским кодом",
"piped_link": "Piped веза", "piped_link": "Piped веза",
"back_to_home": "Врати се на почетну", "back_to_home": "Врати се на почетну",

View File

@ -87,7 +87,6 @@
"with_timecode": "Zaman Koduyla Paylaş", "with_timecode": "Zaman Koduyla Paylaş",
"piped_link": "Piped Bağlantısı", "piped_link": "Piped Bağlantısı",
"share": "Paylaş", "share": "Paylaş",
"rename_playlist": "Oynatma Listesini Yeniden Adlandır",
"new_playlist_name": "Yeni Oynatma Listesi Adı", "new_playlist_name": "Yeni Oynatma Listesi Adı",
"show_chapters": "Bölümler", "show_chapters": "Bölümler",
"store_search_history": "Arama Geçmişini Sakla", "store_search_history": "Arama Geçmişini Sakla",

View File

@ -79,7 +79,6 @@
"logout": "Вийти з цього пристрою", "logout": "Вийти з цього пристрою",
"backup_preferences": "Налаштування резервного копіювання", "backup_preferences": "Налаштування резервного копіювання",
"download_as_txt": "Завантажити як .txt", "download_as_txt": "Завантажити як .txt",
"rename_playlist": "Перейменувати список відтворення",
"show_chapters": "Розділи", "show_chapters": "Розділи",
"invalidate_session": "Вийти з усіх пристроїв", "invalidate_session": "Вийти з усіх пристроїв",
"clone_playlist": "Клонувати список відтворення", "clone_playlist": "Клонувати список відтворення",

View File

@ -87,7 +87,6 @@
"share": "分享", "share": "分享",
"with_timecode": "用时间码分享", "with_timecode": "用时间码分享",
"time_code": "时间码(单位:秒)", "time_code": "时间码(单位:秒)",
"rename_playlist": "重命名播放列表",
"new_playlist_name": "新播放列表名", "new_playlist_name": "新播放列表名",
"show_chapters": "章节", "show_chapters": "章节",
"store_search_history": "保存搜索历史", "store_search_history": "保存搜索历史",

View File

@ -64,7 +64,6 @@
"download_as_txt": "以 .txt 下載", "download_as_txt": "以 .txt 下載",
"share": "分享", "share": "分享",
"new_playlist_name": "播放清單的新名稱", "new_playlist_name": "播放清單的新名稱",
"rename_playlist": "重新命名播放清單",
"reset_preferences": "重設偏好設定", "reset_preferences": "重設偏好設定",
"confirm_reset_preferences": "確定要重設偏好設定嗎?", "confirm_reset_preferences": "確定要重設偏好設定嗎?",
"backup_preferences": "備份偏好設定", "backup_preferences": "備份偏好設定",

1298
yarn.lock

File diff suppressed because it is too large Load Diff