mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-11-25 23:17:22 +00:00
Reuse actions.okay string
This commit is contained in:
commit
0300718377
105
CODE_OF_CONDUCT.md
Normal file
105
CODE_OF_CONDUCT.md
Normal 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
|
20
package.json
20
package.json
@ -23,29 +23,29 @@
|
||||
"stream-browserify": "3.0.0",
|
||||
"vue": "3.3.4",
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-router": "4.2.1",
|
||||
"vue-router": "4.2.2",
|
||||
"xml-js": "1.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/fa6-brands": "1.1.11",
|
||||
"@iconify-json/fa6-solid": "1.1.13",
|
||||
"@intlify/vite-plugin-vue-i18n": "6.0.3",
|
||||
"@unocss/preset-icons": "0.52.1",
|
||||
"@unocss/preset-web-fonts": "0.52.1",
|
||||
"@unocss/transformer-directives": "0.52.1",
|
||||
"@unocss/transformer-variant-group": "0.52.1",
|
||||
"@vitejs/plugin-legacy": "4.0.3",
|
||||
"@unocss/preset-icons": "0.52.5",
|
||||
"@unocss/preset-web-fonts": "0.52.5",
|
||||
"@unocss/transformer-directives": "0.52.5",
|
||||
"@unocss/transformer-variant-group": "0.52.5",
|
||||
"@vitejs/plugin-legacy": "4.0.4",
|
||||
"@vitejs/plugin-vue": "4.2.3",
|
||||
"@vue/compiler-sfc": "3.3.4",
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-prettier": "8.8.0",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"eslint-plugin-vue": "9.14.0",
|
||||
"eslint-plugin-vue": "9.14.1",
|
||||
"prettier": "2.8.8",
|
||||
"unocss": "0.52.1",
|
||||
"vite": "4.3.8",
|
||||
"unocss": "0.52.5",
|
||||
"vite": "4.3.9",
|
||||
"vite-plugin-eslint": "1.8.1",
|
||||
"vite-plugin-pwa": "0.15.0"
|
||||
"vite-plugin-pwa": "0.15.2"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
@ -216,8 +216,10 @@ b {
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
@apply border-2 border-red-500 outline-none;
|
||||
box-shadow: 0 0 15px rgba(239, 68, 68, var(--un-border-opacity));
|
||||
@apply outline-red-500;
|
||||
outline-style: solid;
|
||||
outline-width: 2px;
|
||||
box-shadow: 0 0 15px rgba(239, 68, 68, 1);
|
||||
}
|
||||
|
||||
hr {
|
||||
|
@ -42,19 +42,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<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>
|
||||
<CollapsableText :text="channel.description" />
|
||||
|
||||
<WatchOnYouTubeButton :link="`https://youtube.com/channel/${this.channel.id}`" />
|
||||
|
||||
@ -90,6 +78,7 @@ import ErrorHandler from "./ErrorHandler.vue";
|
||||
import ContentItem from "./ContentItem.vue";
|
||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||
import CollapsableText from "./CollapsableText.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -97,6 +86,7 @@ export default {
|
||||
ContentItem,
|
||||
WatchOnYouTubeButton,
|
||||
LoadingIndicatorPage,
|
||||
CollapsableText,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -105,7 +95,6 @@ export default {
|
||||
tabs: [],
|
||||
selectedTab: 0,
|
||||
contentItems: [],
|
||||
fullDescription: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
28
src/components/CollapsableText.vue
Normal file
28
src/components/CollapsableText.vue
Normal 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>
|
@ -4,7 +4,7 @@
|
||||
<h3 class="text-xl" v-text="message" />
|
||||
<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.confirm'" @click="$emit('confirm')" />
|
||||
<button class="btn" v-t="'actions.okay'" @click="$emit('confirm')" />
|
||||
</div>
|
||||
</div>
|
||||
</ModalComponent>
|
||||
|
@ -1,40 +1,49 @@
|
||||
<template>
|
||||
<h1 v-t="'titles.feed'" class="font-bold text-center my-4" />
|
||||
|
||||
<button class="btn mr-2" @click="exportHandler">
|
||||
<router-link to="/subscriptions">Subscriptions</router-link>
|
||||
</button>
|
||||
<div class="flex flex-wrap md:items-center flex-col md:flex-row gap-2 children:(flex gap-1 items-center)">
|
||||
<span>
|
||||
<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>
|
||||
<a :href="getRssUrl">
|
||||
<span>
|
||||
<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" />
|
||||
</a>
|
||||
</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 />
|
||||
|
||||
<LoadingIndicatorPage :show-content="videosStore != null" class="video-grid">
|
||||
|
@ -1,14 +1,12 @@
|
||||
<template>
|
||||
<h1 class="font-bold text-center" v-t="'titles.history'" />
|
||||
|
||||
<div class="flex">
|
||||
<div>
|
||||
<button class="btn" v-t="'actions.clear_history'" @click="clearHistory" />
|
||||
<div class="flex md:items-center gap-2 flex-col md:flex-row">
|
||||
<button class="btn" v-t="'actions.clear_history'" @click="clearHistory" />
|
||||
|
||||
<button class="btn mx-3" v-t="'actions.export_to_json'" @click="exportHistory" />
|
||||
</div>
|
||||
<button class="btn" v-t="'actions.export_to_json'" @click="exportHistory" />
|
||||
|
||||
<div class="right-1">
|
||||
<div class="ml-auto flex gap-1 items-center">
|
||||
<SortingSelector by-key="watchedAt" @apply="order => videos.sort(order)" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,13 +45,13 @@ export default {
|
||||
}
|
||||
|
||||
.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 {
|
||||
@apply bg-dark-700;
|
||||
}
|
||||
|
||||
.modal-container > button {
|
||||
@apply absolute right-8 top-6;
|
||||
@apply absolute right-2.5 top-1;
|
||||
}
|
||||
</style>
|
||||
|
@ -59,35 +59,41 @@
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- navigation bar for mobile devices -->
|
||||
<ul
|
||||
<div
|
||||
v-if="showTopNav"
|
||||
class="flex flex-col justify-center items-end mb-4 children:(my-0.5 mr-5)"
|
||||
@click="showTopNav = false"
|
||||
class="mobile-nav flex flex-col mb-4 children:(p-1 w-full border-b border-dark-100 flex items-center gap-1)"
|
||||
>
|
||||
<li v-if="shouldShowTrending">
|
||||
<router-link v-t="'titles.trending'" to="/trending" />
|
||||
</li>
|
||||
<li>
|
||||
<router-link v-t="'titles.preferences'" to="/preferences" />
|
||||
</li>
|
||||
<li v-if="shouldShowLogin">
|
||||
<router-link v-t="'titles.login'" to="/login" />
|
||||
</li>
|
||||
<li v-if="shouldShowLogin">
|
||||
<router-link v-t="'titles.register'" to="/register" />
|
||||
</li>
|
||||
<li v-if="shouldShowHistory">
|
||||
<router-link v-t="'titles.history'" to="/history" />
|
||||
</li>
|
||||
<li>
|
||||
<router-link v-t="'titles.playlists'" to="/playlists" />
|
||||
</li>
|
||||
<li v-if="!shouldShowTrending">
|
||||
<router-link v-t="'titles.feed'" to="/feed" />
|
||||
</li>
|
||||
</ul>
|
||||
<router-link v-if="shouldShowTrending" to="/trending">
|
||||
<div class="i-fa6-solid:fire"></div>
|
||||
<i18n-t keypath="titles.trending"></i18n-t>
|
||||
</router-link>
|
||||
<router-link to="/preferences">
|
||||
<div class="i-fa6-solid:gear"></div>
|
||||
<i18n-t keypath="titles.preferences"></i18n-t>
|
||||
</router-link>
|
||||
<router-link v-if="shouldShowLogin" to="/login">
|
||||
<div class="i-fa6-solid:user"></div>
|
||||
<i18n-t keypath="titles.login"></i18n-t>
|
||||
</router-link>
|
||||
<router-link v-if="shouldShowLogin" to="/register">
|
||||
<div class="i-fa6-solid:user-plus"></div>
|
||||
<i18n-t keypath="titles.register"></i18n-t>
|
||||
</router-link>
|
||||
<router-link v-if="shouldShowHistory" to="/history">
|
||||
<div class="i-fa6-solid:clock-rotate-left"></div>
|
||||
<i18n-t keypath="titles.history"></i18n-t>
|
||||
</router-link>
|
||||
<router-link to="/playlists">
|
||||
<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 -->
|
||||
<div class="mobile-search md:hidden mx-2 search-container">
|
||||
<div class="w-full mb-2 md:hidden search-container">
|
||||
<input
|
||||
v-model="searchText"
|
||||
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];
|
||||
line-height: 1.05;
|
||||
}
|
||||
.mobile-search {
|
||||
width: calc(100% - 1rem);
|
||||
@apply mx-2;
|
||||
.mobile-nav div {
|
||||
@apply mx-1;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,20 +1,21 @@
|
||||
<template>
|
||||
<ErrorHandler v-if="playlist && playlist.error" :message="playlist.message" :error="playlist.error" />
|
||||
|
||||
<LoadingIndicatorPage :show-content="playlist" v-show="!playlist.error">
|
||||
<h1 class="text-center my-4" v-text="playlist.name" />
|
||||
<LoadingIndicatorPage :show-content="playlist" v-show="!playlist?.error">
|
||||
<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>
|
||||
<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" />
|
||||
<strong v-text="playlist.uploader" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div>
|
||||
<strong v-text="`${playlist.videos} ${$t('video.videos')}`" />
|
||||
<br />
|
||||
<button class="btn mr-1" v-if="!isPipedPlaylist" @click="bookmarkPlaylist">
|
||||
<strong v-text="`${playlist.videos} ${$t('video.videos')}`" class="mr-2" />
|
||||
<button class="btn mx-1" v-if="!isPipedPlaylist" @click="bookmarkPlaylist">
|
||||
{{ $t(`actions.${isBookmarked ? "playlist_bookmarked" : "bookmark_playlist"}`)
|
||||
}}<font-awesome-icon class="ml-3" icon="bookmark" />
|
||||
</button>
|
||||
@ -52,6 +53,7 @@
|
||||
<script>
|
||||
import ErrorHandler from "./ErrorHandler.vue";
|
||||
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||
import CollapsableText from "./CollapsableText.vue";
|
||||
import VideoItem from "./VideoItem.vue";
|
||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||
|
||||
@ -61,6 +63,7 @@ export default {
|
||||
VideoItem,
|
||||
WatchOnYouTubeButton,
|
||||
LoadingIndicatorPage,
|
||||
CollapsableText,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -39,8 +39,26 @@
|
||||
v-text="playlist.name"
|
||||
/>
|
||||
</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'" />
|
||||
<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
|
||||
v-if="playlistToDelete == playlist.id"
|
||||
:message="$t('actions.delete_playlist_confirm')"
|
||||
@ -83,6 +101,7 @@
|
||||
|
||||
<script>
|
||||
import ConfirmModal from "./ConfirmModal.vue";
|
||||
import ModalComponent from "./ModalComponent.vue";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -90,6 +109,9 @@ export default {
|
||||
playlists: [],
|
||||
bookmarks: [],
|
||||
playlistToDelete: null,
|
||||
playlistToEdit: null,
|
||||
newPlaylistName: "",
|
||||
newPlaylistDescription: "",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
@ -109,30 +131,48 @@ export default {
|
||||
this.playlists = json;
|
||||
});
|
||||
},
|
||||
renamePlaylist(id) {
|
||||
const newName = prompt(this.$t("actions.new_playlist_name"));
|
||||
if (!newName) return;
|
||||
this.fetchJson(this.authApiUrl() + "/user/playlists/rename", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
playlistId: id,
|
||||
newName: newName,
|
||||
}),
|
||||
headers: {
|
||||
Authorization: this.getAuthToken(),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).then(json => {
|
||||
if (json.error) alert(json.error);
|
||||
else {
|
||||
this.playlists.forEach((playlist, index) => {
|
||||
if (playlist.id == id) {
|
||||
this.playlists[index].name = newName;
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
showPlaylistEditModal(playlist) {
|
||||
this.newPlaylistName = playlist.name;
|
||||
this.newPlaylistDescription = playlist.description;
|
||||
this.playlistToEdit = playlist.id;
|
||||
},
|
||||
editPlaylist(selectedPlaylist) {
|
||||
// save the new name and description since they could be overwritten during the http request
|
||||
const newName = this.newPlaylistName;
|
||||
const newDescription = this.newPlaylistDescription;
|
||||
if (newName != selectedPlaylist.name) {
|
||||
this.fetchJson(this.authApiUrl() + "/user/playlists/rename", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
playlistId: selectedPlaylist.id,
|
||||
newName: newName,
|
||||
}),
|
||||
headers: {
|
||||
Authorization: this.getAuthToken(),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).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) {
|
||||
this.fetchJson(this.authApiUrl() + "/user/playlists/delete", null, {
|
||||
@ -271,6 +311,6 @@ export default {
|
||||
this.bookmarks.splice(index, 1);
|
||||
},
|
||||
},
|
||||
components: { ConfirmModal },
|
||||
components: { ConfirmModal, ModalComponent },
|
||||
};
|
||||
</script>
|
||||
|
@ -82,7 +82,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 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 {
|
||||
@ -98,6 +98,6 @@ export default {
|
||||
}
|
||||
|
||||
.suggestion {
|
||||
@apply p-y-1;
|
||||
@apply p-1;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<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" />
|
||||
</select>
|
||||
</template>
|
||||
|
@ -43,13 +43,13 @@
|
||||
<div class="font-bold mt-2 text-2xl break-words" v-text="video.title" />
|
||||
<div class="flex flex-wrap mt-3 mb-3">
|
||||
<!-- 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> | </span>
|
||||
<span v-text="uploadDate" />
|
||||
</div>
|
||||
<!-- Likes/dilikes -->
|
||||
<div class="flex children:mr-2">
|
||||
<div class="flex gap-2">
|
||||
<template v-if="video.likes >= 0">
|
||||
<div class="flex items-center">
|
||||
<div class="i-fa6-solid:thumbs-up" />
|
||||
@ -68,7 +68,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- Channel info & options flex container -->
|
||||
<div class="flex">
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<!-- Channel Image & Info -->
|
||||
<div class="flex items-center">
|
||||
<img :src="video.uploaderAvatar" alt="" loading="lazy" class="rounded-full" />
|
||||
@ -78,19 +78,6 @@
|
||||
<!-- Verified Badge -->
|
||||
<font-awesome-icon class="ml-1" v-if="video.uploaderVerified" icon="check" />
|
||||
</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" />
|
||||
<ShareModal
|
||||
v-if="showShareModal"
|
||||
@ -100,8 +87,20 @@
|
||||
:playlist-index="index"
|
||||
@close="showShareModal = !showShareModal"
|
||||
/>
|
||||
<div class="flex">
|
||||
<div class="self-center children:mr-1 my-1">
|
||||
<div class="flex flex-wrap gap-1 ml-auto">
|
||||
<!-- 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 -->
|
||||
<a
|
||||
aria-label="RSS feed"
|
||||
@ -110,18 +109,22 @@
|
||||
v-if="video.uploaderUrl"
|
||||
:href="`${apiUrl()}/feed/unauthenticated/rss?channels=${video.uploaderUrl.split('/')[2]}`"
|
||||
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>
|
||||
<WatchOnYouTubeButton :link="`https://youtu.be/${getVideoId()}`" />
|
||||
<!-- 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>
|
||||
<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">
|
||||
<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>
|
||||
</a>
|
||||
<!-- listen / watch toggle -->
|
||||
@ -129,9 +132,9 @@
|
||||
:to="toggleListenUrl"
|
||||
:aria-label="(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>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -107,7 +107,6 @@
|
||||
"follow_link": "اتبع الرابط",
|
||||
"copy_link": "نسخ الرابط",
|
||||
"time_code": "رمز الوقت (بالثواني)",
|
||||
"rename_playlist": "إعادة تسمية قائمة التشغيل",
|
||||
"new_playlist_name": "اسم قائمة تشغيل جديد",
|
||||
"show_chapters": "الفصول",
|
||||
"store_search_history": "حفظ سجل البحث",
|
||||
|
@ -100,7 +100,6 @@
|
||||
"instance_auth_selection": "Təsdiqləmə Nümunəsi Seçimi",
|
||||
"clone_playlist": "Oynatma Siyahısın Klonla",
|
||||
"clone_playlist_success": "Uğurla klonlandı!",
|
||||
"rename_playlist": "Oynatma siyahısın yenidən adlandır",
|
||||
"time_code": "Vaxt kodu (saniyələrlə)",
|
||||
"store_search_history": "Axtarış tarixçəsini saxla",
|
||||
"documentation": "Sənədləşdirmə",
|
||||
|
@ -99,7 +99,6 @@
|
||||
"clone_playlist": "Клониране на плейлист",
|
||||
"clone_playlist_success": "Успешно клониране!",
|
||||
"backup_preferences": "Архивиране на настройките",
|
||||
"rename_playlist": "Преименуване на плейлиста",
|
||||
"new_playlist_name": "Ново име на плейлиста",
|
||||
"back_to_home": "Обратно към начална страница",
|
||||
"status_page": "Статус",
|
||||
|
@ -77,7 +77,6 @@
|
||||
"minimize_chapters_default": "Smanjite poglavlja po zadanom",
|
||||
"show_watch_on_youtube": "Prikaži „Gledaj na YouTube-u” dugme",
|
||||
"different_auth_instance": "Koristite drugu instancu za autentifikaciju",
|
||||
"rename_playlist": "Preimenuj listu izvođenja",
|
||||
"new_playlist_name": "Novi naziv liste izvođenja",
|
||||
"with_timecode": "Podijelite s vremenskim kodom",
|
||||
"piped_link": "Piped poveznica",
|
||||
|
@ -103,7 +103,6 @@
|
||||
"time_code": "Moment (en segons)",
|
||||
"copy_link": "Copiar 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ó",
|
||||
"store_search_history": "Emmagatzema l'historial de cerca",
|
||||
"instance_donations": "Donacions a instàncies",
|
||||
|
@ -104,7 +104,6 @@
|
||||
"follow_link": "Otevřít odkaz",
|
||||
"copy_link": "Kopírovat odkaz",
|
||||
"time_code": "Časový kód (v sekundách)",
|
||||
"rename_playlist": "Přejmenovat playlist",
|
||||
"new_playlist_name": "Nový název playlistu",
|
||||
"show_chapters": "Kapitoly",
|
||||
"store_search_history": "Ukládat historii vyhledávání",
|
||||
|
@ -75,7 +75,6 @@
|
||||
"instance_auth_selection": "Auswahl der Autentifizierungsinstanz",
|
||||
"clone_playlist": "Playlist duplizieren",
|
||||
"clone_playlist_success": "Erfolgreich dupliziert!",
|
||||
"rename_playlist": "Playlist umbenennen",
|
||||
"new_playlist_name": "Neuer Name der Playlist",
|
||||
"piped_link": "Piped-Link",
|
||||
"download_as_txt": "Als .txt herunterladen",
|
||||
|
@ -111,7 +111,9 @@
|
||||
"backup_preferences": "Backup preferences",
|
||||
"restore_preferences": "Restore preferences",
|
||||
"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",
|
||||
"share": "Share",
|
||||
"with_timecode": "Share with time code",
|
||||
@ -137,7 +139,7 @@
|
||||
"create_group": "Create group",
|
||||
"group_name": "Group name",
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm"
|
||||
"okay": "Okay"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Pinned by {author}",
|
||||
|
@ -55,7 +55,6 @@
|
||||
"hide_replies": "Kaŝi Respondojn",
|
||||
"add_to_playlist": "Aldoni al ludlisto",
|
||||
"delete_playlist": "Forigi Ludliston",
|
||||
"rename_playlist": "Renomi ludliston",
|
||||
"download_as_txt": "Elŝuti kiel .txt",
|
||||
"piped_link": "Piped-ligilo",
|
||||
"copy_link": "Kopii ligilon",
|
||||
|
@ -103,7 +103,6 @@
|
||||
"invalidate_session": "Cerrar sesión en todos los dispositivos",
|
||||
"instance_auth_selection": "Selección de la Instancia de Autentificación",
|
||||
"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",
|
||||
"share": "Compartir",
|
||||
"with_timecode": "Compartir con código de tiempo",
|
||||
|
@ -101,7 +101,6 @@
|
||||
"show_watch_on_youtube": "Näytä Katso YouTubessa -painike",
|
||||
"different_auth_instance": "Käytä eri instanssia todennukseen",
|
||||
"download_as_txt": "Lataa .txt-tiedostona",
|
||||
"rename_playlist": "Nimeä soittolista uudelleen",
|
||||
"show_chapters": "Luvut",
|
||||
"minimize_comments": "Minimoi kommentit",
|
||||
"minimize_comments_default": "Minimoi kommentit oletusarvoisesti",
|
||||
|
@ -103,7 +103,6 @@
|
||||
"piped_link": "Lien vers Piped",
|
||||
"follow_link": "Ouvrir le lien",
|
||||
"time_code": "Horodatage (en secondes)",
|
||||
"rename_playlist": "Renommer la liste de lecture",
|
||||
"new_playlist_name": "Nouveau nom de la liste de lecture",
|
||||
"show_chapters": "Chapitres",
|
||||
"store_search_history": "Mémoriser l'historique de recherche",
|
||||
|
@ -104,7 +104,6 @@
|
||||
"search": "חיפוש (Ctrl+K)",
|
||||
"loop_this_video": "ניגון הסרטון בלולאה",
|
||||
"minimize_recommendations": "מזעור המלצות",
|
||||
"rename_playlist": "שינוי שם רשימת נגינה",
|
||||
"new_playlist_name": "שם לרשימת נגינה חדשה",
|
||||
"show_chapters": "פרקים",
|
||||
"skip_intro": "דילוג על הפוגה/הנפשת הקדמה",
|
||||
|
@ -113,7 +113,6 @@
|
||||
"confirm_reset_preferences": "Stvarno želiš resetirati tvoje postavke?",
|
||||
"backup_preferences": "Spremi sigurnosnu kopiju postavki",
|
||||
"with_timecode": "Dijeli s vremenskim kodom",
|
||||
"rename_playlist": "Preimenuj popis snimaka",
|
||||
"new_playlist_name": "Ime novog popisa snimaka",
|
||||
"share": "Dijeli",
|
||||
"show_chapters": "Poglavlja",
|
||||
@ -140,7 +139,8 @@
|
||||
"autoplay_next_countdown": "Standardno odbrojavanje do sljedećeg videa (u sekundama)",
|
||||
"dismiss": "Odbaci",
|
||||
"create_group": "Stvori grupu",
|
||||
"group_name": "Ime grupe"
|
||||
"group_name": "Ime grupe",
|
||||
"auto_display_captions": "Automatski prikaži titlove"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Gledaj na {0}"
|
||||
|
@ -92,7 +92,6 @@
|
||||
"clone_playlist_success": "Sikeresen klónozva!",
|
||||
"reset_preferences": "Alaphelyzetbe állítás",
|
||||
"restore_preferences": "Beállítások betöltése fájlból",
|
||||
"rename_playlist": "Átnevez",
|
||||
"instance_donations": "Szerver adományozások",
|
||||
"piped_link": "Piped link",
|
||||
"time_code": "Idő kód (másodpercekben)",
|
||||
|
@ -76,7 +76,6 @@
|
||||
"confirm_reset_preferences": "Իսկապե՞ս ուզում եք վերակայել ձեր նախապատվությունները:",
|
||||
"backup_preferences": "Պահուստային նախապատվություններ",
|
||||
"restore_preferences": "Վերականգնել նախապատվությունները",
|
||||
"rename_playlist": "Վերանվանել տեսացանկը",
|
||||
"new_playlist_name": "Տեսացանկի նոր անվանում",
|
||||
"follow_link": "Հետևել հղմանը",
|
||||
"instance_donations": "Օրինակների նվիրատվություններ",
|
||||
|
@ -100,7 +100,6 @@
|
||||
"restore_preferences": "Pulihkan preferensi",
|
||||
"confirm_reset_preferences": "Apakah Anda yakin ingin mengatur ulang preferensi Anda?",
|
||||
"backup_preferences": "Cadangkan preferensi",
|
||||
"rename_playlist": "Ubah nama daftar putar",
|
||||
"new_playlist_name": "Nama daftar putar baru",
|
||||
"share": "Bagikan",
|
||||
"with_timecode": "Bagikan dengan kode waktu",
|
||||
|
@ -12,7 +12,9 @@
|
||||
"account": "Reikningur",
|
||||
"instance": "Tilvik",
|
||||
"livestreams": "Útsendingar í beinni",
|
||||
"channels": "Rásir"
|
||||
"channels": "Rásir",
|
||||
"bookmarks": "Bókamerki",
|
||||
"channel_groups": "Rásarhópar"
|
||||
},
|
||||
"actions": {
|
||||
"sort_by": "Raða eftir:",
|
||||
@ -94,7 +96,6 @@
|
||||
"instance_donations": "Framlög til netþjóns",
|
||||
"status_page": "Staða",
|
||||
"source_code": "Frumkóði",
|
||||
"rename_playlist": "Endurnefna spilunarlista",
|
||||
"new_playlist_name": "Nýtt heiti spilunarlista",
|
||||
"share": "Deila",
|
||||
"with_timecode": "Deilа með tímakóða",
|
||||
|
@ -88,7 +88,6 @@
|
||||
"follow_link": "Apri il collegamento",
|
||||
"with_timecode": "Condividi con marca temporale",
|
||||
"new_playlist_name": "Nuovo nome dalla playlist",
|
||||
"rename_playlist": "Rinomina la playlist",
|
||||
"show_chapters": "Capitoli",
|
||||
"store_search_history": "Memorizza la cronologia delle ricerche",
|
||||
"status_page": "Stato",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"channel_groups": "グループ"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "{0}上で視聴"
|
||||
"watch_on": "{0}で視聴"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "チャンネル登録 - {count}",
|
||||
@ -29,13 +29,13 @@
|
||||
"channel_name_asc": "チャンネル名 (AからZ)",
|
||||
"channel_name_desc": "チャンネル名 (ZからA)",
|
||||
"back": "戻る",
|
||||
"uses_api_from": "API使用元 ",
|
||||
"uses_api_from": "API 提供元 ",
|
||||
"enable_sponsorblock": "SponsorBlock を有効化",
|
||||
"skip_sponsors": "広告をスキップ",
|
||||
"skip_intro": "休止時間/導入アニメをスキップ",
|
||||
"skip_outro": "終了シーン/クレジットをスキップ",
|
||||
"skip_preview": "プレビュー/要約をスキップ",
|
||||
"skip_interaction": "チャンネル登録など操作を求める自己宣伝をスキップ",
|
||||
"skip_interaction": "登録など操作を頼む自己宣伝をスキップ",
|
||||
"skip_self_promo": "無報酬/自己の宣伝をスキップ",
|
||||
"skip_non_music": "音楽: 非音楽部分をスキップ",
|
||||
"theme": "テーマ",
|
||||
@ -43,14 +43,14 @@
|
||||
"dark": "ダーク",
|
||||
"light": "ライト",
|
||||
"autoplay_video": "動画を自動再生",
|
||||
"audio_only": "音声のみ",
|
||||
"audio_only": "音声のみのモード",
|
||||
"default_quality": "標準の画質",
|
||||
"buffering_goal": "バッファリング目標値 (秒)",
|
||||
"country_selection": "国の選択",
|
||||
"default_homepage": "ホームに表示するページ",
|
||||
"show_comments": "コメントを表示",
|
||||
"minimize_description_default": "最初から説明を最小化",
|
||||
"store_watch_history": "再生履歴を保存する",
|
||||
"store_watch_history": "再生履歴を保存",
|
||||
"language_selection": "言語の選択",
|
||||
"instances_list": "インスタンス一覧",
|
||||
"enabled_codecs": "コーデックの有効化 (複数選択)",
|
||||
@ -68,7 +68,7 @@
|
||||
"minimize_recommendations": "おすすめを最小化",
|
||||
"show_recommendations": "おすすめを見る",
|
||||
"disable_lbry": "ストリーミングのLBRYを無効化",
|
||||
"enable_lbry_proxy": "LBRYプロキシをオン",
|
||||
"enable_lbry_proxy": "LBRYにプロキシを使用",
|
||||
"view_ssl_score": "SSLの評価を表示",
|
||||
"search": "検索 (Ctrl+K)",
|
||||
"filter": "フィルター",
|
||||
@ -87,8 +87,8 @@
|
||||
"show_markers": "プレイヤーに目印の区切りを表示",
|
||||
"select_playlist": "再生リストを選択",
|
||||
"delete_playlist_confirm": "再生リストを削除しますか?",
|
||||
"delete_account": "アカウントを削除する",
|
||||
"store_search_history": "検索履歴を保存する",
|
||||
"delete_account": "アカウントを削除",
|
||||
"store_search_history": "検索履歴を保存",
|
||||
"show_chapters": "チャプター",
|
||||
"status_page": "状態",
|
||||
"source_code": "ソースコード",
|
||||
@ -96,15 +96,15 @@
|
||||
"minimize_comments": "コメントを最小化",
|
||||
"share": "共有",
|
||||
"with_timecode": "時間指定で共有",
|
||||
"different_auth_instance": "認証に別のインスタンスを使う",
|
||||
"different_auth_instance": "認証には別のインスタンスを使う",
|
||||
"download_as_txt": ".txtでダウンロード",
|
||||
"logout": "このデバイスでログアウト",
|
||||
"logout": "この端末からログアウト",
|
||||
"minimize_recommendations_default": "最初からおすすめを最小化",
|
||||
"hide_watched": "再生済みの動画をフィードに表示しない",
|
||||
"minimize_chapters_default": "最初からチャプターを最小化",
|
||||
"show_watch_on_youtube": "「YouTubeで見る」ボタンを表示する",
|
||||
"invalidate_session": "すべてのデバイスでログアウトする",
|
||||
"instance_auth_selection": "認証インスタンスの選択",
|
||||
"show_watch_on_youtube": "「YouTubeで視聴」ボタンを表示",
|
||||
"invalidate_session": "すべての端末からログアウト",
|
||||
"instance_auth_selection": "認証用インスタンスの選択",
|
||||
"clone_playlist_success": "複製に成功しました!",
|
||||
"backup_preferences": "設定をバックアップ",
|
||||
"restore_preferences": "設定を復元",
|
||||
@ -114,7 +114,6 @@
|
||||
"documentation": "ドキュメント",
|
||||
"reset_preferences": "設定を初期化",
|
||||
"confirm_reset_preferences": "設定をリセットしますか?",
|
||||
"rename_playlist": "再生リスト名を変更する",
|
||||
"piped_link": "Pipedリンク",
|
||||
"new_playlist_name": "新しい再生リスト名",
|
||||
"follow_link": "リンクを開く",
|
||||
@ -147,7 +146,7 @@
|
||||
"instance_locations": "インスタンスの場所",
|
||||
"has_cdn": "CDNの有無",
|
||||
"ssl_score": "SSLの評価",
|
||||
"registered_users": "登録ユーザー数",
|
||||
"registered_users": "登録利用者数",
|
||||
"version": "バージョン",
|
||||
"up_to_date": "最新?"
|
||||
},
|
||||
@ -184,8 +183,8 @@
|
||||
"cannot_copy": "コピーできません!",
|
||||
"preferences_note": "注意: 設定は、お使いのブラウザの保存領域に保存されます。ブラウザのデータを削除すると初期化されます。",
|
||||
"local_storage": "この操作にはlocalStorageが必要です。Cookieは有効ですか?",
|
||||
"register_no_email_note": "Eメールアドレスをユーザー名として使用することは推奨されていません。それでも続行しますか?",
|
||||
"next_video_countdown": "{0} 秒後に次の動画を再生"
|
||||
"register_no_email_note": "ユーザー名としてのメールアドレスの使用は推奨しません。それでも続けますか?",
|
||||
"next_video_countdown": "{0} 秒後に次の動画"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "チャンネル登録: {0}"
|
||||
|
@ -98,7 +98,6 @@
|
||||
"backup_preferences": "Ḥrez ismenyifen",
|
||||
"restore_preferences": "Err-d ismenyifen",
|
||||
"back_to_home": "Uɣal ɣer ugejdan",
|
||||
"rename_playlist": "Beddel isem i tebdart n tɣuri",
|
||||
"follow_link": "Ḍfer aseɣwen",
|
||||
"show_chapters": "Ixfawen",
|
||||
"show_watch_on_youtube": "Sken taqeffalt Wali ɣef YouTube",
|
||||
|
@ -70,7 +70,6 @@
|
||||
"show_chapters": "챕터",
|
||||
"download_as_txt": ".txt로 다운로드",
|
||||
"new_playlist_name": "새 재생목록 이름",
|
||||
"rename_playlist": "재생목록 이름 변경",
|
||||
"share": "공유",
|
||||
"copy_link": "링크 복사",
|
||||
"time_code": "시작 시간 (초)",
|
||||
|
@ -80,7 +80,6 @@
|
||||
"reply_count": "{count} atsakymai",
|
||||
"show_chapters": "Skirsniai",
|
||||
"piped_link": "Piped nuoroda",
|
||||
"rename_playlist": "Pervardyti grojaraštį",
|
||||
"follow_link": "Sekti nuorodą",
|
||||
"store_search_history": "Išsaugoti paieškos istoriją",
|
||||
"hide_watched": "Slėpti žiūrėtus vaizdo įrašus sklaidos kanale",
|
||||
|
@ -81,7 +81,6 @@
|
||||
"confirm_reset_preferences": "Tilbakestill alle innstillingene?",
|
||||
"restore_preferences": "Gjenopprett innstillinger",
|
||||
"show_chapters": "Kapitler",
|
||||
"rename_playlist": "Gi spillelisten ny navn",
|
||||
"new_playlist_name": "Nytt spillelistenavn",
|
||||
"share": "Del",
|
||||
"with_timecode": "Del med tidskode",
|
||||
|
@ -80,7 +80,6 @@
|
||||
"instance_auth_selection": "Selectie authenticatie-instantie",
|
||||
"clone_playlist": "Afspeellijst dupliceren",
|
||||
"download_as_txt": "Downloaden als .txt",
|
||||
"rename_playlist": "Afspeellijst hernoemen",
|
||||
"new_playlist_name": "Nieuwe afspeellijstnaam",
|
||||
"share": "Delen",
|
||||
"documentation": "Documentatie",
|
||||
|
@ -98,7 +98,6 @@
|
||||
"invalidate_session": "Se desconnectar de totes los aparelhs",
|
||||
"different_auth_instance": "Utilizar una instància diferenta per l’autentificacion",
|
||||
"back_to_home": "Tornar a l’acuèlh",
|
||||
"rename_playlist": "Renomenar la lista de lectura",
|
||||
"new_playlist_name": "Nom novèl de la lista de lectura",
|
||||
"with_timecode": "Partejar amb còdi orari",
|
||||
"piped_link": "Ligam cap a Piped",
|
||||
|
@ -35,7 +35,6 @@
|
||||
"show_recommendations": "ସୁପାରିଶଗୁଡିକ ଦେଖାନ୍ତୁ",
|
||||
"disable_lbry": "ଷ୍ଟ୍ରିମିଂ ପାଇଁ LBRY ଅକ୍ଷମ କରନ୍ତୁ",
|
||||
"search": "ସନ୍ଧାନ କରନ୍ତୁ (Ctrl+K)",
|
||||
"rename_playlist": "ପ୍ଲେ ଲିଷ୍ଟର ନାମ ପରିବର୍ତ୍ତନ କରନ୍ତୁ",
|
||||
"new_playlist_name": "ନୂତନ ପ୍ଲେଲିଷ୍ଟ ନାମ",
|
||||
"channel_name_asc": "ସ୍ରୋତ ର ନାମ (A-Z)",
|
||||
"least_recent": "ସର୍ବନିମ୍ନ ସାମ୍ପ୍ରତିକ",
|
||||
|
@ -102,7 +102,6 @@
|
||||
"source_code": "Kod źródłowy",
|
||||
"show_chapters": "Rozdziały",
|
||||
"minimize_chapters_default": "Ukryj rozdziały",
|
||||
"rename_playlist": "Zmień nazwę playlisty",
|
||||
"follow_link": "Otwórz link",
|
||||
"minimize_comments_default": "Ukryj sekcję komentarzy",
|
||||
"minimize_comments": "Ukryj komentarze",
|
||||
|
@ -110,7 +110,6 @@
|
||||
"new_playlist_name": "Novo nome da lista de reprodução",
|
||||
"minimize_comments": "Minimizar Comentários",
|
||||
"back_to_home": "Voltar ao início",
|
||||
"rename_playlist": "Renomear",
|
||||
"copy_link": "Copiar ligação",
|
||||
"time_code": "Código de tempo (em segundos)",
|
||||
"minimize_comments_default": "Minimizar Comentários por defeito",
|
||||
@ -130,7 +129,8 @@
|
||||
"dismiss": "Ignorar",
|
||||
"autoplay_next_countdown": "Predefinição Contagem decrescente até ao próximo vídeo (em segundos)",
|
||||
"create_group": "Criar grupo",
|
||||
"group_name": "Nome do grupo"
|
||||
"group_name": "Nome do grupo",
|
||||
"auto_display_captions": "Visualização automática de legendas"
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "Nome da Instância",
|
||||
|
@ -87,7 +87,6 @@
|
||||
"restore_preferences": "Restaurar preferências",
|
||||
"back_to_home": "Voltar ao início",
|
||||
"share": "Compartilhar",
|
||||
"rename_playlist": "Renomear playlist",
|
||||
"new_playlist_name": "Novo nome da playlist",
|
||||
"with_timecode": "Compartilhar com código de tempo",
|
||||
"piped_link": "Link do Piped",
|
||||
|
@ -93,7 +93,6 @@
|
||||
"invalidate_session": "Terminar sessão em todos os aparelhos",
|
||||
"clone_playlist": "Clonar Lista de Reprodução",
|
||||
"clone_playlist_success": "Clonada com sucesso!",
|
||||
"rename_playlist": "Renomear",
|
||||
"restore_preferences": "Restaurar 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",
|
||||
@ -130,7 +129,8 @@
|
||||
"autoplay_next_countdown": "Predefinição Contagem decrescente até ao próximo vídeo (em segundos)",
|
||||
"dismiss": "Ignorar",
|
||||
"create_group": "Criar grupo",
|
||||
"group_name": "Nome do grupo"
|
||||
"group_name": "Nome do grupo",
|
||||
"auto_display_captions": "Visualização automática de legendas"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Afixado por {author}",
|
||||
|
@ -59,7 +59,6 @@
|
||||
"clone_playlist_success": "Clonată cu succes!",
|
||||
"reset_preferences": "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",
|
||||
"share": "Distribuiți",
|
||||
"follow_link": "Urmați link-ul",
|
||||
|
@ -97,7 +97,6 @@
|
||||
"clone_playlist": "Клонировать плейлист",
|
||||
"clone_playlist_success": "Успешно клонировано!",
|
||||
"show_chapters": "Главы",
|
||||
"rename_playlist": "Переименовать плейлист",
|
||||
"new_playlist_name": "Новое название плейлиста",
|
||||
"share": "Поделиться",
|
||||
"with_timecode": "Поделиться с таймкодом",
|
||||
|
@ -81,7 +81,6 @@
|
||||
"backup_preferences": "සැකසුම් උපස්ථ කරන්න",
|
||||
"restore_preferences": "සැකසුම් නැවත පිහිටුවන්න",
|
||||
"back_to_home": "ආපසු මුල් පිටුවට",
|
||||
"rename_playlist": "වාදන ලැයිස්තුව නැවත නම් කරන්න",
|
||||
"share": "බෙදාගන්න",
|
||||
"with_timecode": "කාල කේතය සමඟ බෙදා ගන්න",
|
||||
"piped_link": "පයිප්ඩ් සබැඳිය",
|
||||
|
@ -72,7 +72,6 @@
|
||||
"view_ssl_score": "Zobraziť SSL skóre",
|
||||
"filter": "Filter",
|
||||
"delete_playlist_video_confirm": "Odstrániť video zo zoznamu?",
|
||||
"rename_playlist": "Premenovať zoznam skladieb",
|
||||
"new_playlist_name": "Nový názov zoznamu skladieb",
|
||||
"share": "Zdieľať",
|
||||
"follow_link": "Nasledujte odkaz",
|
||||
|
@ -100,7 +100,6 @@
|
||||
"status_page": "Статус",
|
||||
"instance_donations": "Донације инстанци",
|
||||
"show_chapters": "Поглавља",
|
||||
"rename_playlist": "Преименуј плејлисту",
|
||||
"with_timecode": "Подели са временским кодом",
|
||||
"piped_link": "Piped веза",
|
||||
"back_to_home": "Врати се на почетну",
|
||||
|
@ -87,7 +87,6 @@
|
||||
"with_timecode": "Zaman Koduyla Paylaş",
|
||||
"piped_link": "Piped Bağlantısı",
|
||||
"share": "Paylaş",
|
||||
"rename_playlist": "Oynatma Listesini Yeniden Adlandır",
|
||||
"new_playlist_name": "Yeni Oynatma Listesi Adı",
|
||||
"show_chapters": "Bölümler",
|
||||
"store_search_history": "Arama Geçmişini Sakla",
|
||||
|
@ -79,7 +79,6 @@
|
||||
"logout": "Вийти з цього пристрою",
|
||||
"backup_preferences": "Налаштування резервного копіювання",
|
||||
"download_as_txt": "Завантажити як .txt",
|
||||
"rename_playlist": "Перейменувати список відтворення",
|
||||
"show_chapters": "Розділи",
|
||||
"invalidate_session": "Вийти з усіх пристроїв",
|
||||
"clone_playlist": "Клонувати список відтворення",
|
||||
|
@ -87,7 +87,6 @@
|
||||
"share": "分享",
|
||||
"with_timecode": "用时间码分享",
|
||||
"time_code": "时间码(单位:秒)",
|
||||
"rename_playlist": "重命名播放列表",
|
||||
"new_playlist_name": "新播放列表名",
|
||||
"show_chapters": "章节",
|
||||
"store_search_history": "保存搜索历史",
|
||||
|
@ -64,7 +64,6 @@
|
||||
"download_as_txt": "以 .txt 下載",
|
||||
"share": "分享",
|
||||
"new_playlist_name": "播放清單的新名稱",
|
||||
"rename_playlist": "重新命名播放清單",
|
||||
"reset_preferences": "重設偏好設定",
|
||||
"confirm_reset_preferences": "確定要重設偏好設定嗎?",
|
||||
"backup_preferences": "備份偏好設定",
|
||||
|
Loading…
Reference in New Issue
Block a user