mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-11-23 14:07:24 +00:00
Make eslint work, and fix all warnings. (#511)
* Make eslint work, and fix all warnings. * Don't ignore v-html rule globally. * Remove eslint file and merge in package.json.
This commit is contained in:
parent
41ac97ed92
commit
92d61a23af
@ -1,5 +1,3 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: ["@vue/cli-plugin-babel/preset"],
|
||||||
'@vue/cli-plugin-babel/preset'
|
};
|
||||||
]
|
|
||||||
}
|
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
"@vue/compiler-sfc": "3.2.19",
|
"@vue/compiler-sfc": "3.2.19",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-config-prettier": "^8.3.0",
|
||||||
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"eslint-plugin-vue": "^7.19.1"
|
"eslint-plugin-vue": "^7.19.1"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
@ -43,6 +45,7 @@
|
|||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"plugin:vue/vue3-essential",
|
"plugin:vue/vue3-essential",
|
||||||
|
"plugin:prettier/recommended",
|
||||||
"eslint:recommended"
|
"eslint:recommended"
|
||||||
],
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<Navigation />
|
<Navigation />
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<keep-alive :max="5">
|
<keep-alive :max="5">
|
||||||
<component :key="$route.fullPath" :is="Component" />
|
<component :is="Component" :key="$route.fullPath" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</router-view>
|
</router-view>
|
||||||
|
|
||||||
|
@ -3,17 +3,18 @@
|
|||||||
|
|
||||||
<div v-if="channel" v-show="!channel.error">
|
<div v-if="channel" v-show="!channel.error">
|
||||||
<h1 class="uk-text-center">
|
<h1 class="uk-text-center">
|
||||||
<img height="48" width="48" class="uk-border-circle" v-bind:src="channel.avatarUrl" />{{ channel.name }}
|
<img height="48" width="48" class="uk-border-circle" :src="channel.avatarUrl" />{{ channel.name }}
|
||||||
</h1>
|
</h1>
|
||||||
<img v-if="channel.bannerUrl" v-bind:src="channel.bannerUrl" style="width: 100%" loading="lazy" />
|
<img v-if="channel.bannerUrl" :src="channel.bannerUrl" style="width: 100%" loading="lazy" />
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<p style="white-space: pre-wrap"><span v-html="purifyHTML(urlify(channel.description))"></span></p>
|
<p style="white-space: pre-wrap"><span v-html="purifyHTML(urlify(channel.description))"></span></p>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="authenticated"
|
v-if="authenticated"
|
||||||
@click="subscribeHandler"
|
|
||||||
class="uk-button uk-button-small"
|
class="uk-button uk-button-small"
|
||||||
style="background: #222"
|
style="background: #222"
|
||||||
type="button"
|
type="button"
|
||||||
|
@click="subscribeHandler"
|
||||||
>
|
>
|
||||||
{{ subscribed ? $t("actions.unsubscribe") : $t("actions.subscribe") }}
|
{{ subscribed ? $t("actions.unsubscribe") : $t("actions.subscribe") }}
|
||||||
</button>
|
</button>
|
||||||
@ -22,11 +23,11 @@
|
|||||||
|
|
||||||
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
||||||
<div
|
<div
|
||||||
|
v-for="video in channel.relatedStreams"
|
||||||
|
:key="video.url"
|
||||||
class="uk-width-1-2 uk-width-1-3@m uk-width-1-4@l uk-width-1-5@xl"
|
class="uk-width-1-2 uk-width-1-3@m uk-width-1-4@l uk-width-1-5@xl"
|
||||||
v-bind:key="video.url"
|
|
||||||
v-for="video in this.channel.relatedStreams"
|
|
||||||
>
|
>
|
||||||
<VideoItem :video="video" height="94" width="168" hideChannel />
|
<VideoItem :video="video" height="94" width="168" hide-channel />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -37,6 +38,10 @@ import ErrorHandler from "@/components/ErrorHandler.vue";
|
|||||||
import VideoItem from "@/components/VideoItem.vue";
|
import VideoItem from "@/components/VideoItem.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
ErrorHandler,
|
||||||
|
VideoItem,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
channel: null,
|
channel: null,
|
||||||
@ -116,9 +121,5 @@ export default {
|
|||||||
this.subscribed = !this.subscribed;
|
this.subscribed = !this.subscribed;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
ErrorHandler,
|
|
||||||
VideoItem,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,47 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="comment uk-flex">
|
<div class="comment uk-flex">
|
||||||
<img
|
<img
|
||||||
:src="comment.thumbnail"
|
:src="comment.thumbnail"
|
||||||
class="comment-avatar uk-border-circle uk-margin-right"
|
class="comment-avatar uk-border-circle uk-margin-right"
|
||||||
style="width: 48px; height: 48px;"
|
style="width: 48px; height: 48px;"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
alt="Avatar"
|
alt="Avatar"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="comment-content">
|
<div class="comment-content">
|
||||||
<div class="comment-header">
|
<div class="comment-header">
|
||||||
<div v-if="comment.pinned" class="comment-pinned uk-text-meta">
|
<div v-if="comment.pinned" class="comment-pinned uk-text-meta">
|
||||||
<font-awesome-icon icon="thumbtack"></font-awesome-icon> {{ $t("comment.pinned_by") }}
|
<font-awesome-icon icon="thumbtack"></font-awesome-icon> {{ $t("comment.pinned_by") }}
|
||||||
{{ uploader }}
|
{{ uploader }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="comment-author">
|
<div class="comment-author">
|
||||||
<router-link class="uk-text-bold uk-text-small" v-bind:to="comment.commentorUrl">
|
<router-link class="uk-text-bold uk-text-small" :to="comment.commentorUrl">
|
||||||
{{ comment.author }} </router-link
|
{{ comment.author }} </router-link
|
||||||
> <font-awesome-icon v-if="comment.verified" icon="check"></font-awesome-icon>
|
> <font-awesome-icon v-if="comment.verified" icon="check"></font-awesome-icon>
|
||||||
|
</div>
|
||||||
|
<div class="comment-meta uk-text-meta uk-margin-small-bottom">
|
||||||
|
{{ comment.commentedTime }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="comment-body" style="white-space: pre-wrap">
|
||||||
|
{{ comment.commentText }}
|
||||||
|
</div>
|
||||||
|
<div class="comment-footer uk-margin-small-top uk-text-meta">
|
||||||
|
<font-awesome-icon icon="thumbs-up" style="margin-right: 4px;"></font-awesome-icon>
|
||||||
|
<span>{{ numberFormat(comment.likeCount) }}</span>
|
||||||
|
|
||||||
|
<font-awesome-icon v-if="comment.hearted" icon="heart"></font-awesome-icon>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="comment-meta uk-text-meta uk-margin-small-bottom">
|
|
||||||
{{ comment.commentedTime }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="comment-body" style="white-space: pre-wrap">
|
|
||||||
{{ comment.commentText }}
|
|
||||||
</div>
|
|
||||||
<div class="comment-footer uk-margin-small-top uk-text-meta">
|
|
||||||
<font-awesome-icon icon="thumbs-up" style="margin-right: 4px;"></font-awesome-icon>
|
|
||||||
<span>{{ numberFormat(comment.likeCount) }}</span>
|
|
||||||
|
|
||||||
<font-awesome-icon v-if="comment.hearted" icon="heart"></font-awesome-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
comment: Object,
|
comment: {
|
||||||
uploader: String
|
type: Object,
|
||||||
}
|
default: () => {
|
||||||
}
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
uploader: { type: String, default: null },
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
@ -9,8 +9,8 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
error: String,
|
error: { type: String, default: null },
|
||||||
message: String,
|
message: { type: String, default: null },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<h1 class="uk-text-bold uk-text-center" v-t="'titles.feed'" />
|
<h1 v-t="'titles.feed'" class="uk-text-bold uk-text-center" />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="authenticated"
|
v-if="authenticated"
|
||||||
@click="exportHandler"
|
|
||||||
class="uk-button uk-button-small"
|
class="uk-button uk-button-small"
|
||||||
style="background: #222; margin-right: 0.5rem"
|
style="background: #222; margin-right: 0.5rem"
|
||||||
type="button"
|
type="button"
|
||||||
|
@click="exportHandler"
|
||||||
>
|
>
|
||||||
<router-link to="/subscriptions">
|
<router-link to="/subscriptions">
|
||||||
Subscriptions
|
Subscriptions
|
||||||
@ -19,11 +19,11 @@
|
|||||||
|
|
||||||
<span class="uk-align-right@m">
|
<span class="uk-align-right@m">
|
||||||
<label for="ddlSortBy">{{ $t("actions.sort_by") }}</label>
|
<label for="ddlSortBy">{{ $t("actions.sort_by") }}</label>
|
||||||
<select id="ddlSortBy" class="uk-select uk-width-auto" v-model="selectedSort" @change="onChange()">
|
<select id="ddlSortBy" v-model="selectedSort" class="uk-select uk-width-auto" @change="onChange()">
|
||||||
<option value="descending" v-t="'actions.most_recent'" />
|
<option v-t="'actions.most_recent'" value="descending" />
|
||||||
<option value="ascending" v-t="'actions.least_recent'" />
|
<option v-t="'actions.least_recent'" value="ascending" />
|
||||||
<option value="channel_ascending" v-t="'actions.channel_name_asc'" />
|
<option v-t="'actions.channel_name_asc'" value="channel_ascending" />
|
||||||
<option value="channel_descending" v-t="'actions.channel_name_desc'" />
|
<option v-t="'actions.channel_name_desc'" value="channel_descending" />
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@ -31,10 +31,10 @@
|
|||||||
|
|
||||||
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
||||||
<div
|
<div
|
||||||
|
v-for="video in videos"
|
||||||
|
:key="video.url"
|
||||||
:style="[{ background: backgroundColor }]"
|
:style="[{ background: backgroundColor }]"
|
||||||
class="uk-width-1-1 uk-width-1-3@s uk-width-1-4@m uk-width-1-5@l uk-width-1-6@xl"
|
class="uk-width-1-1 uk-width-1-3@s uk-width-1-4@m uk-width-1-5@l uk-width-1-6@xl"
|
||||||
v-bind:key="video.url"
|
|
||||||
v-for="video in videos"
|
|
||||||
>
|
>
|
||||||
<VideoItem :video="video" />
|
<VideoItem :video="video" />
|
||||||
</div>
|
</div>
|
||||||
@ -45,6 +45,9 @@
|
|||||||
import VideoItem from "@/components/VideoItem.vue";
|
import VideoItem from "@/components/VideoItem.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VideoItem,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentVideoCount: 0,
|
currentVideoCount: 0,
|
||||||
@ -54,6 +57,11 @@ export default {
|
|||||||
selectedSort: "descending",
|
selectedSort: "descending",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
getRssUrl(_this) {
|
||||||
|
return _this.apiUrl() + "/feed/rss?authToken=" + _this.getAuthToken();
|
||||||
|
},
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.fetchFeed().then(videos => {
|
this.fetchFeed().then(videos => {
|
||||||
this.videosStore = videos;
|
this.videosStore = videos;
|
||||||
@ -105,13 +113,5 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
getRssUrl(_this) {
|
|
||||||
return _this.apiUrl() + "/feed/rss?authToken=" + _this.getAuthToken();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
VideoItem,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<h1 class="uk-text-bold uk-text-center">{{ $t("titles.history") }}</h1>
|
<h1 class="uk-text-bold uk-text-center">{{ $t("titles.history") }}</h1>
|
||||||
|
|
||||||
|
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
<label for="ddlSortBy">{{ $t("actions.sort_by") }}</label>
|
<label for="ddlSortBy">{{ $t("actions.sort_by") }}</label>
|
||||||
<select id="ddlSortBy" class="uk-select uk-width-auto" v-model="selectedSort" @change="onChange()">
|
<select id="ddlSortBy" v-model="selectedSort" class="uk-select uk-width-auto" @change="onChange()">
|
||||||
<option value="descending" v-t="'actions.most_recent'" />
|
<option v-t="'actions.most_recent'" value="descending" />
|
||||||
<option value="ascending" v-t="'actions.least_recent'" />
|
<option v-t="'actions.least_recent'" value="ascending" />
|
||||||
<option value="channel_ascending" v-t="'actions.channel_name_asc'" />
|
<option v-t="'actions.channel_name_asc'" value="channel_ascending" />
|
||||||
<option value="channel_descending" v-t="'actions.channel_name_desc'" />
|
<option v-t="'actions.channel_name_desc'" value="channel_descending" />
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -16,10 +15,10 @@
|
|||||||
|
|
||||||
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
||||||
<div
|
<div
|
||||||
|
v-for="video in videos"
|
||||||
|
:key="video.url"
|
||||||
:style="[{ background: backgroundColor }]"
|
:style="[{ background: backgroundColor }]"
|
||||||
class="uk-width-1-2 uk-width-1-3@s uk-width-1-4@m uk-width-1-5@l uk-width-1-6@xl"
|
class="uk-width-1-2 uk-width-1-3@s uk-width-1-4@m uk-width-1-5@l uk-width-1-6@xl"
|
||||||
v-bind:key="video.url"
|
|
||||||
v-for="video in videos"
|
|
||||||
>
|
>
|
||||||
<VideoItem :video="video" />
|
<VideoItem :video="video" />
|
||||||
</div>
|
</div>
|
||||||
@ -32,6 +31,9 @@
|
|||||||
import VideoItem from "@/components/VideoItem.vue";
|
import VideoItem from "@/components/VideoItem.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VideoItem,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
videos: [],
|
videos: [],
|
||||||
@ -85,8 +87,5 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
VideoItem,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
<div class="uk-vertical-align uk-text-center uk-height-1-1 ">
|
<div class="uk-vertical-align uk-text-center uk-height-1-1 ">
|
||||||
<form class="uk-panel uk-panel-box">
|
<form class="uk-panel uk-panel-box">
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<input type="file" @change="fileChange" ref="fileSelector" />
|
<input ref="fileSelector" type="file" @change="fileChange" />
|
||||||
</div>
|
</div>
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<b>Selected Subscriptions: {{ selectedSubscriptions }}</b>
|
<b>Selected Subscriptions: {{ selectedSubscriptions }}</b>
|
||||||
</div>
|
</div>
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<b>Override: <input class="uk-checkbox" v-model="override" type="checkbox"/></b>
|
<b>Override: <input v-model="override" class="uk-checkbox" type="checkbox"/></b>
|
||||||
</div>
|
</div>
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<a
|
<a
|
||||||
@ -79,7 +79,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fileChange() {
|
fileChange() {
|
||||||
const file = this.$refs.fileSelector.files[0]
|
const file = this.$refs.fileSelector.files[0];
|
||||||
file.text().then(text => {
|
file.text().then(text => {
|
||||||
this.subscriptions = [];
|
this.subscriptions = [];
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
<form class="uk-panel uk-panel-box">
|
<form class="uk-panel uk-panel-box">
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<input
|
<input
|
||||||
|
v-model="username"
|
||||||
class="uk-width-1-1 uk-form-large uk-input uk-width-auto"
|
class="uk-width-1-1 uk-form-large uk-input uk-width-auto"
|
||||||
type="text"
|
type="text"
|
||||||
v-model="username"
|
|
||||||
autocomplete="username"
|
autocomplete="username"
|
||||||
:placeholder="$t('login.username')"
|
:placeholder="$t('login.username')"
|
||||||
:aria-label="$t('login.username')"
|
:aria-label="$t('login.username')"
|
||||||
@ -13,9 +13,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<input
|
<input
|
||||||
|
v-model="password"
|
||||||
class="uk-width-1-1 uk-form-large uk-input uk-width-auto"
|
class="uk-width-1-1 uk-form-large uk-input uk-width-auto"
|
||||||
type="password"
|
type="password"
|
||||||
v-model="password"
|
|
||||||
autocomplete="password"
|
autocomplete="password"
|
||||||
:placeholder="$t('login.password')"
|
:placeholder="$t('login.password')"
|
||||||
:aria-label="$t('login.password')"
|
:aria-label="$t('login.password')"
|
||||||
@ -26,8 +26,9 @@
|
|||||||
class="uk-width-1-1 uk-button uk-button-primary uk-button-large uk-width-auto"
|
class="uk-width-1-1 uk-button uk-button-primary uk-button-large uk-width-auto"
|
||||||
style="background: #222"
|
style="background: #222"
|
||||||
@click="login"
|
@click="login"
|
||||||
> {{ $t('titles.login') }} </a
|
|
||||||
>
|
>
|
||||||
|
{{ $t("titles.login") }}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="uk-navbar-center uk-flex uk-visible@m">
|
<div class="uk-navbar-center uk-flex uk-visible@m">
|
||||||
<input
|
<input
|
||||||
|
v-model="searchText"
|
||||||
class="uk-input uk-width-medium"
|
class="uk-input uk-width-medium"
|
||||||
type="text"
|
type="text"
|
||||||
role="search"
|
role="search"
|
||||||
:title="$t('actions.search')"
|
:title="$t('actions.search')"
|
||||||
:placeholder="$t('actions.search')"
|
:placeholder="$t('actions.search')"
|
||||||
v-model="searchText"
|
|
||||||
@keyup="onKeyUp"
|
@keyup="onKeyUp"
|
||||||
@focus="onInputFocus"
|
@focus="onInputFocus"
|
||||||
@blur="onInputBlur"
|
@blur="onInputBlur"
|
||||||
@ -31,31 +31,31 @@
|
|||||||
<div class="uk-navbar-right">
|
<div class="uk-navbar-right">
|
||||||
<ul class="uk-navbar-nav">
|
<ul class="uk-navbar-nav">
|
||||||
<li>
|
<li>
|
||||||
<router-link to="/preferences" v-t="'titles.preferences'" />
|
<router-link v-t="'titles.preferences'" to="/preferences" />
|
||||||
</li>
|
</li>
|
||||||
<li v-if="shouldShowLogin">
|
<li v-if="shouldShowLogin">
|
||||||
<router-link to="/login" v-t="'titles.login'" />
|
<router-link v-t="'titles.login'" to="/login" />
|
||||||
</li>
|
</li>
|
||||||
<li v-if="shouldShowLogin">
|
<li v-if="shouldShowLogin">
|
||||||
<router-link to="/register" v-t="'titles.register'" />
|
<router-link v-t="'titles.register'" to="/register" />
|
||||||
</li>
|
</li>
|
||||||
<li v-if="shouldShowHistory">
|
<li v-if="shouldShowHistory">
|
||||||
<router-link to="/history" v-t="'titles.history'" />
|
<router-link v-t="'titles.history'" to="/history" />
|
||||||
</li>
|
</li>
|
||||||
<li v-if="authenticated">
|
<li v-if="authenticated">
|
||||||
<router-link to="/feed" v-t="'titles.feed'" />
|
<router-link v-t="'titles.feed'" to="/feed" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="uk-container-expand uk-hidden@m">
|
<div class="uk-container-expand uk-hidden@m">
|
||||||
<input
|
<input
|
||||||
|
v-model="searchText"
|
||||||
class="uk-input"
|
class="uk-input"
|
||||||
type="text"
|
type="text"
|
||||||
role="search"
|
role="search"
|
||||||
:title="$t('actions.search')"
|
:title="$t('actions.search')"
|
||||||
:placeholder="$t('actions.search')"
|
:placeholder="$t('actions.search')"
|
||||||
v-model="searchText"
|
|
||||||
@keyup="onKeyUp"
|
@keyup="onKeyUp"
|
||||||
@focus="onInputFocus"
|
@focus="onInputFocus"
|
||||||
@blur="onInputBlur"
|
@blur="onInputBlur"
|
||||||
@ -63,9 +63,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<SearchSuggestions
|
<SearchSuggestions
|
||||||
v-show="searchText && suggestionsVisible"
|
v-show="searchText && suggestionsVisible"
|
||||||
:searchText="searchText"
|
|
||||||
@searchchange="onSearchTextChange"
|
|
||||||
ref="searchSuggestions"
|
ref="searchSuggestions"
|
||||||
|
:search-text="searchText"
|
||||||
|
@searchchange="onSearchTextChange"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,40 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="uk-container-expand">
|
<div class="uk-container-expand">
|
||||||
<div
|
<div
|
||||||
|
ref="container"
|
||||||
data-shaka-player-container
|
data-shaka-player-container
|
||||||
style="width: 100%; height: 100%; background: #000"
|
style="width: 100%; height: 100%; background: #000"
|
||||||
:style="!isEmbed ? { 'max-height': '75vh', 'min-height': '250px' } : {}"
|
:style="!isEmbed ? { 'max-height': '75vh', 'min-height': '250px' } : {}"
|
||||||
ref="container"
|
|
||||||
>
|
>
|
||||||
<video
|
<video
|
||||||
|
ref="videoEl"
|
||||||
data-shaka-player
|
data-shaka-player
|
||||||
class="uk-width-expand"
|
class="uk-width-expand"
|
||||||
:autoplay="shouldAutoPlay"
|
:autoplay="shouldAutoPlay"
|
||||||
:loop="selectedAutoLoop"
|
:loop="selectedAutoLoop"
|
||||||
ref="videoEl"
|
|
||||||
></video>
|
></video>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
|
||||||
.shaka-text-container > div {
|
|
||||||
height: auto !important;
|
|
||||||
width: auto !important;
|
|
||||||
top: auto !important;
|
|
||||||
left: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shaka-text-container * {
|
|
||||||
background-color: rgba(8, 8, 8, 0.75) !important;
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shaka-video-container:-webkit-full-screen {
|
|
||||||
max-height: none !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import("shaka-player/dist/controls.css");
|
import("shaka-player/dist/controls.css");
|
||||||
const shaka = import("shaka-player/dist/shaka-player.ui.js");
|
const shaka = import("shaka-player/dist/shaka-player.ui.js");
|
||||||
@ -43,8 +25,18 @@ window.muxjs = muxjs;
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
video: Object,
|
video: {
|
||||||
sponsors: Object,
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sponsors: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
selectedAutoPlay: Boolean,
|
selectedAutoPlay: Boolean,
|
||||||
selectedAutoLoop: Boolean,
|
selectedAutoLoop: Boolean,
|
||||||
isEmbed: Boolean,
|
isEmbed: Boolean,
|
||||||
@ -82,6 +74,63 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
if (!this.shaka) this.shakaPromise = shaka.then(shaka => shaka.default).then(shaka => (this.shaka = shaka));
|
if (!this.shaka) this.shakaPromise = shaka.then(shaka => shaka.default).then(shaka => (this.shaka = shaka));
|
||||||
},
|
},
|
||||||
|
activated() {
|
||||||
|
import("hotkeys-js")
|
||||||
|
.then(mod => mod.default)
|
||||||
|
.then(hotkeys => {
|
||||||
|
this.hotkeys = hotkeys;
|
||||||
|
var self = this;
|
||||||
|
hotkeys("f,m,j,k,l,space,up,down,left,right", function(e, handler) {
|
||||||
|
const videoEl = self.$refs.videoEl;
|
||||||
|
switch (handler.key) {
|
||||||
|
case "f":
|
||||||
|
self.$ui.getControls().toggleFullScreen();
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case "m":
|
||||||
|
videoEl.muted = !videoEl.muted;
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case "j":
|
||||||
|
videoEl.currentTime = Math.max(videoEl.currentTime - 15, 0);
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case "l":
|
||||||
|
videoEl.currentTime = videoEl.currentTime + 15;
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case "k":
|
||||||
|
case "space":
|
||||||
|
if (videoEl.paused) videoEl.play();
|
||||||
|
else videoEl.pause();
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case "up":
|
||||||
|
videoEl.volume = Math.min(videoEl.volume + 0.05, 1);
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case "down":
|
||||||
|
videoEl.volume = Math.max(videoEl.volume - 0.05, 0);
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
videoEl.currentTime = Math.max(videoEl.currentTime - 5, 0);
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case "right":
|
||||||
|
videoEl.currentTime = videoEl.currentTime + 5;
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deactivated() {
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
|
unmounted() {
|
||||||
|
this.destroy();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadVideo() {
|
async loadVideo() {
|
||||||
const component = this;
|
const component = this;
|
||||||
@ -304,62 +353,23 @@ export default {
|
|||||||
if (this.$refs.container) this.$refs.container.querySelectorAll("div").forEach(node => node.remove());
|
if (this.$refs.container) this.$refs.container.querySelectorAll("div").forEach(node => node.remove());
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
activated() {
|
|
||||||
import("hotkeys-js")
|
|
||||||
.then(mod => mod.default)
|
|
||||||
.then(hotkeys => {
|
|
||||||
this.hotkeys = hotkeys;
|
|
||||||
var self = this;
|
|
||||||
hotkeys("f,m,j,k,l,space,up,down,left,right", function(e, handler) {
|
|
||||||
const videoEl = self.$refs.videoEl;
|
|
||||||
switch (handler.key) {
|
|
||||||
case "f":
|
|
||||||
self.$ui.getControls().toggleFullScreen();
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case "m":
|
|
||||||
videoEl.muted = !videoEl.muted;
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case "j":
|
|
||||||
videoEl.currentTime = Math.max(videoEl.currentTime - 15, 0);
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case "l":
|
|
||||||
videoEl.currentTime = videoEl.currentTime + 15;
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case "k":
|
|
||||||
case "space":
|
|
||||||
if (videoEl.paused) videoEl.play();
|
|
||||||
else videoEl.pause();
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case "up":
|
|
||||||
videoEl.volume = Math.min(videoEl.volume + 0.05, 1);
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case "down":
|
|
||||||
videoEl.volume = Math.max(videoEl.volume - 0.05, 0);
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case "left":
|
|
||||||
videoEl.currentTime = Math.max(videoEl.currentTime - 5, 0);
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
case "right":
|
|
||||||
videoEl.currentTime = videoEl.currentTime + 5;
|
|
||||||
e.preventDefault();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deactivated() {
|
|
||||||
this.destroy();
|
|
||||||
},
|
|
||||||
unmounted() {
|
|
||||||
this.destroy();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.shaka-text-container > div {
|
||||||
|
height: auto !important;
|
||||||
|
width: auto !important;
|
||||||
|
top: auto !important;
|
||||||
|
left: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shaka-text-container * {
|
||||||
|
background-color: rgba(8, 8, 8, 0.75) !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shaka-video-container:-webkit-full-screen {
|
||||||
|
max-height: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
<div v-if="playlist" v-show="!playlist.error">
|
<div v-if="playlist" v-show="!playlist.error">
|
||||||
<h1 class="uk-text-center">
|
<h1 class="uk-text-center">
|
||||||
<img v-bind:src="playlist.avatarUrl" height="48" width="48" loading="lazy"/>
|
<img :src="playlist.avatarUrl" height="48" width="48" loading="lazy" />
|
||||||
{{ playlist.name }}
|
{{ playlist.name }}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<b
|
<b
|
||||||
><router-link class="uk-text-justify" v-bind:to="playlist.uploaderUrl || '/'">
|
><router-link class="uk-text-justify" :to="playlist.uploaderUrl || '/'">
|
||||||
<img v-bind:src="playlist.uploaderAvatar" loading="lazy" class="uk-border-circle" />
|
<img :src="playlist.uploaderAvatar" loading="lazy" class="uk-border-circle" />
|
||||||
{{ playlist.uploader }}</router-link
|
{{ playlist.uploader }}</router-link
|
||||||
></b
|
></b
|
||||||
>
|
>
|
||||||
@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
||||||
<div
|
<div
|
||||||
|
v-for="video in playlist.relatedStreams"
|
||||||
|
:key="video.url"
|
||||||
class="uk-width-1-2 uk-width-1-3@m uk-width-1-4@l uk-width-1-5@xl"
|
class="uk-width-1-2 uk-width-1-3@m uk-width-1-4@l uk-width-1-5@xl"
|
||||||
v-bind:key="video.url"
|
|
||||||
v-for="video in this.playlist.relatedStreams"
|
|
||||||
>
|
>
|
||||||
<VideoItem :video="video" height="94" width="168" />
|
<VideoItem :video="video" height="94" width="168" />
|
||||||
</div>
|
</div>
|
||||||
@ -39,11 +39,20 @@ import ErrorHandler from "@/components/ErrorHandler.vue";
|
|||||||
import VideoItem from "@/components/VideoItem.vue";
|
import VideoItem from "@/components/VideoItem.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
ErrorHandler,
|
||||||
|
VideoItem,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
playlist: null,
|
playlist: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
getRssUrl: _this => {
|
||||||
|
return _this.apiUrl() + "/rss/playlists/" + _this.$route.query.list;
|
||||||
|
},
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getPlaylistData();
|
this.getPlaylistData();
|
||||||
},
|
},
|
||||||
@ -53,11 +62,6 @@ export default {
|
|||||||
deactivated() {
|
deactivated() {
|
||||||
window.removeEventListener("scroll", this.handleScroll);
|
window.removeEventListener("scroll", this.handleScroll);
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
getRssUrl: _this => {
|
|
||||||
return _this.apiUrl() + "/rss/playlists/" + _this.$route.query.list;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
async fetchPlaylist() {
|
async fetchPlaylist() {
|
||||||
return await await this.fetchJson(this.apiUrl() + "/playlists/" + this.$route.query.list);
|
return await await this.fetchJson(this.apiUrl() + "/playlists/" + this.$route.query.list);
|
||||||
@ -82,9 +86,5 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
ErrorHandler,
|
|
||||||
VideoItem,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<button class="uk-button uk-button-text" @click="$router.go(-1) || $router.push('/')">
|
<button class="uk-button uk-button-text" @click="$router.go(-1) || $router.push('/')">
|
||||||
<font-awesome-icon icon="chevron-left" /> {{ $t("actions.back") }}
|
<font-awesome-icon icon="chevron-left" /> {{ $t("actions.back") }}
|
||||||
</button>
|
</button>
|
||||||
<span><h1 class="uk-text-bold uk-text-center" v-t="'titles.preferences'"/></span>
|
<span><h1 v-t="'titles.preferences'" class="uk-text-bold uk-text-center"/></span>
|
||||||
<span />
|
<span />
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
@ -13,158 +13,163 @@
|
|||||||
<br />
|
<br />
|
||||||
<input
|
<input
|
||||||
id="chkEnableSponsorblock"
|
id="chkEnableSponsorblock"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="sponsorBlock"
|
v-model="sponsorBlock"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="chkSkipSponsors"><b v-t="'actions.skip_sponsors'"/></label>
|
<label for="chkSkipSponsors"><b v-t="'actions.skip_sponsors'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input id="chkSkipSponsors" class="uk-checkbox" v-model="skipSponsor" @change="onChange($event)" type="checkbox" />
|
<input id="chkSkipSponsors" v-model="skipSponsor" class="uk-checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
<br />
|
<br />
|
||||||
<label for="chkSkipIntro"><b v-t="'actions.skip_intro'"/></label>
|
<label for="chkSkipIntro"><b v-t="'actions.skip_intro'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input id="chkSkipIntro" class="uk-checkbox" v-model="skipIntro" @change="onChange($event)" type="checkbox" />
|
<input id="chkSkipIntro" v-model="skipIntro" class="uk-checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
<br />
|
<br />
|
||||||
<label for="chkSkipOutro"><b v-t="'actions.skip_outro'"/></label>
|
<label for="chkSkipOutro"><b v-t="'actions.skip_outro'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input id="chkSkipOutro" class="uk-checkbox" v-model="skipOutro" @change="onChange($event)" type="checkbox" />
|
<input id="chkSkipOutro" v-model="skipOutro" class="uk-checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
<br />
|
<br />
|
||||||
<label for="chkSkipPreview"><b v-t="'actions.skip_preview'"/></label>
|
<label for="chkSkipPreview"><b v-t="'actions.skip_preview'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input id="chkSkipPreview" class="uk-checkbox" v-model="skipPreview" @change="onChange($event)" type="checkbox" />
|
<input id="chkSkipPreview" v-model="skipPreview" class="uk-checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
<br />
|
<br />
|
||||||
<label for="chkSkipInteraction"><b v-t="'actions.skip_interaction'"/></label>
|
<label for="chkSkipInteraction"><b v-t="'actions.skip_interaction'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input
|
||||||
id="chkSkipInteraction"
|
id="chkSkipInteraction"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipInteraction"
|
v-model="skipInteraction"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="chkSkipSelfPromo"><b v-t="'actions.skip_self_promo'"/></label>
|
<label for="chkSkipSelfPromo"><b v-t="'actions.skip_self_promo'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input
|
||||||
id="chkSkipSelfPromo"
|
id="chkSkipSelfPromo"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipSelfPromo"
|
v-model="skipSelfPromo"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="chkSkipNonMusic"><b v-t="'actions.skip_non_music'"/></label>
|
<label for="chkSkipNonMusic"><b v-t="'actions.skip_non_music'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input
|
||||||
id="chkSkipNonMusic"
|
id="chkSkipNonMusic"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipMusicOffTopic"
|
v-model="skipMusicOffTopic"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="ddlTheme"><b v-t="'actions.theme'"/></label>
|
<label for="ddlTheme"><b v-t="'actions.theme'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<select id="ddlTheme" class="uk-select uk-width-auto" v-model="selectedTheme" @change="onChange($event)">
|
<select id="ddlTheme" v-model="selectedTheme" class="uk-select uk-width-auto" @change="onChange($event)">
|
||||||
<option value="auto" v-t="'actions.auto'" />
|
<option v-t="'actions.auto'" value="auto" />
|
||||||
<option value="dark" v-t="'actions.dark'" />
|
<option v-t="'actions.dark'" value="dark" />
|
||||||
<option value="light" v-t="'actions.light'" />
|
<option v-t="'actions.light'" value="light" />
|
||||||
</select>
|
</select>
|
||||||
<br />
|
<br />
|
||||||
<label for="chkAutoPlayVideo"><b v-t="'actions.autoplay_video'"/></label>
|
<label for="chkAutoPlayVideo"><b v-t="'actions.autoplay_video'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input
|
||||||
id="chkAutoPlayVideo"
|
id="chkAutoPlayVideo"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="autoPlayVideo"
|
v-model="autoPlayVideo"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="chkAudioOnly"><b v-t="'actions.audio_only'"/></label>
|
<label for="chkAudioOnly"><b v-t="'actions.audio_only'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input id="chkAudioOnly" class="uk-checkbox" v-model="listen" @change="onChange($event)" type="checkbox" />
|
<input id="chkAudioOnly" v-model="listen" class="uk-checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
<br />
|
<br />
|
||||||
<label for="ddlDefaultQuality"><b v-t="'actions.default_quality'"/></label>
|
<label for="ddlDefaultQuality"><b v-t="'actions.default_quality'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<select id="ddlDefaultQuality" class="uk-select uk-width-auto" v-model="defaultQuality" @change="onChange($event)">
|
<select id="ddlDefaultQuality" v-model="defaultQuality" class="uk-select uk-width-auto" @change="onChange($event)">
|
||||||
<option value="0" v-t="'actions.auto'" />
|
<option v-t="'actions.auto'" value="0" />
|
||||||
<option :key="resolution" v-for="resolution in resolutions" :value="resolution">{{ resolution }}p</option>
|
<option v-for="resolution in resolutions" :key="resolution" :value="resolution">{{ resolution }}p</option>
|
||||||
</select>
|
</select>
|
||||||
<br />
|
<br />
|
||||||
<label for="txtBufferingGoal"><b v-t="'actions.buffering_goal'"/></label>
|
<label for="txtBufferingGoal"><b v-t="'actions.buffering_goal'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input
|
||||||
id="txtBufferingGoal"
|
id="txtBufferingGoal"
|
||||||
class="uk-input uk-width-auto"
|
|
||||||
v-model="bufferingGoal"
|
v-model="bufferingGoal"
|
||||||
@change="onChange($event)"
|
class="uk-input uk-width-auto"
|
||||||
type="text"
|
type="text"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="ddlCountrySelection"><b v-t="'actions.country_selection'"/></label>
|
<label for="ddlCountrySelection"><b v-t="'actions.country_selection'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<select id="ddlCountrySelection" class="uk-select uk-width-auto" v-model="country" @change="onChange($event)">
|
<select
|
||||||
<option :key="country.code" v-for="country in countryMap" :value="country.code">{{ country.name }}</option>
|
id="ddlCountrySelection"
|
||||||
|
v-model="countrySelected"
|
||||||
|
class="uk-select uk-width-auto"
|
||||||
|
@change="onChange($event)"
|
||||||
|
>
|
||||||
|
<option v-for="country in countryMap" :key="country.code" :value="country.code">{{ country.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
<br />
|
<br />
|
||||||
<label for="ddlDefaultHomepage"><b v-t="'actions.default_homepage'"/></label>
|
<label for="ddlDefaultHomepage"><b v-t="'actions.default_homepage'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<select
|
<select
|
||||||
id="ddlDefaultHomepage"
|
id="ddlDefaultHomepage"
|
||||||
class="uk-select uk-width-auto"
|
|
||||||
v-model="defaultHomepage"
|
v-model="defaultHomepage"
|
||||||
|
class="uk-select uk-width-auto"
|
||||||
@change="onChange($event)"
|
@change="onChange($event)"
|
||||||
>
|
>
|
||||||
<option value="trending" v-t="'titles.trending'" />
|
<option v-t="'titles.trending'" value="trending" />
|
||||||
<option value="feed" v-t="'titles.feed'" />
|
<option v-t="'titles.feed'" value="feed" />
|
||||||
</select>
|
</select>
|
||||||
<br />
|
<br />
|
||||||
<label for="chkShowComments"><b v-t="'actions.show_comments'"/></label>
|
<label for="chkShowComments"><b v-t="'actions.show_comments'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input id="chkShowComments" class="uk-checkbox" v-model="showComments" @change="onChange($event)" type="checkbox" />
|
<input id="chkShowComments" v-model="showComments" class="uk-checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
<br />
|
<br />
|
||||||
<label for="chkMinimizeDescription"><b v-t="'actions.minimize_description_default'"/></label>
|
<label for="chkMinimizeDescription"><b v-t="'actions.minimize_description_default'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input
|
||||||
id="chkMinimizeDescription"
|
id="chkMinimizeDescription"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="minimizeDescription"
|
v-model="minimizeDescription"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="chkStoreWatchHistory"><b v-t="'actions.store_watch_history'"/></label>
|
<label for="chkStoreWatchHistory"><b v-t="'actions.store_watch_history'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input
|
||||||
id="chkStoreWatchHistory"
|
id="chkStoreWatchHistory"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="watchHistory"
|
v-model="watchHistory"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="ddlLanguageSelection"><b v-t="'actions.language_selection'"/></label>
|
<label for="ddlLanguageSelection"><b v-t="'actions.language_selection'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<select
|
<select
|
||||||
id="ddlLanguageSelection"
|
id="ddlLanguageSelection"
|
||||||
class="uk-select uk-width-auto"
|
|
||||||
v-model="selectedLanguage"
|
v-model="selectedLanguage"
|
||||||
|
class="uk-select uk-width-auto"
|
||||||
@change="onChange($event)"
|
@change="onChange($event)"
|
||||||
>
|
>
|
||||||
<option :key="language.code" v-for="language in languages" :value="language.code">{{ language.name }}</option>
|
<option v-for="language in languages" :key="language.code" :value="language.code">{{ language.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
<br />
|
<br />
|
||||||
<label for="ddlEnabledCodecs"><b v-t="'actions.enabled_codecs'"/></label>
|
<label for="ddlEnabledCodecs"><b v-t="'actions.enabled_codecs'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<select
|
<select
|
||||||
id="ddlEnabledCodecs"
|
id="ddlEnabledCodecs"
|
||||||
class="uk-select uk-width-auto"
|
|
||||||
v-model="enabledCodecs"
|
v-model="enabledCodecs"
|
||||||
@change="onChange($event)"
|
class="uk-select uk-width-auto"
|
||||||
multiple
|
multiple
|
||||||
|
@change="onChange($event)"
|
||||||
>
|
>
|
||||||
<option value="av1">AV1</option>
|
<option value="av1">AV1</option>
|
||||||
<option value="vp9">VP9</option>
|
<option value="vp9">VP9</option>
|
||||||
@ -173,11 +178,11 @@
|
|||||||
<br />
|
<br />
|
||||||
<label for="chkDisableLBRY"><b v-t="'actions.disable_lbry'"/></label>
|
<label for="chkDisableLBRY"><b v-t="'actions.disable_lbry'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input id="chkDisableLBRY" class="uk-checkbox" v-model="disableLBRY" @change="onChange($event)" type="checkbox" />
|
<input id="chkDisableLBRY" v-model="disableLBRY" class="uk-checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
<br />
|
<br />
|
||||||
<label for="chkEnableLBRYProxy"><b v-t="'actions.enable_lbry_proxy'"/></label>
|
<label for="chkEnableLBRYProxy"><b v-t="'actions.enable_lbry_proxy'"/></label>
|
||||||
<br />
|
<br />
|
||||||
<input id="chkEnableLBRYProxy" class="uk-checkbox" v-model="proxyLBRY" @change="onChange($event)" type="checkbox" />
|
<input id="chkEnableLBRYProxy" v-model="proxyLBRY" class="uk-checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
<h2 v-t="'actions.instances_list'" />
|
<h2 v-t="'actions.instances_list'" />
|
||||||
<table class="uk-table">
|
<table class="uk-table">
|
||||||
<thead>
|
<thead>
|
||||||
@ -188,7 +193,7 @@
|
|||||||
<th>{{ $t("preferences.ssl_score") }}</th>
|
<th>{{ $t("preferences.ssl_score") }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody v-bind:key="instance.name" v-for="instance in instances">
|
<tbody v-for="instance in instances" :key="instance.name">
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ instance.name }}</td>
|
<td>{{ instance.name }}</td>
|
||||||
<td>{{ instance.locations }}</td>
|
<td>{{ instance.locations }}</td>
|
||||||
@ -208,11 +213,11 @@
|
|||||||
<br />
|
<br />
|
||||||
<select
|
<select
|
||||||
id="ddlInstanceSelection"
|
id="ddlInstanceSelection"
|
||||||
class="uk-select uk-width-auto"
|
|
||||||
v-model="selectedInstance"
|
v-model="selectedInstance"
|
||||||
|
class="uk-select uk-width-auto"
|
||||||
@change="onChange($event)"
|
@change="onChange($event)"
|
||||||
>
|
>
|
||||||
<option v-bind:key="instance.name" v-for="instance in instances" v-bind:value="instance.apiurl">
|
<option v-for="instance in instances" :key="instance.name" :value="instance.apiurl">
|
||||||
{{ instance.name }}
|
{{ instance.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@ -240,7 +245,7 @@ export default {
|
|||||||
defaultQuality: 0,
|
defaultQuality: 0,
|
||||||
bufferingGoal: 10,
|
bufferingGoal: 10,
|
||||||
countryMap: CountryMap,
|
countryMap: CountryMap,
|
||||||
country: "US",
|
countrySelected: "US",
|
||||||
defaultHomepage: "trending",
|
defaultHomepage: "trending",
|
||||||
showComments: true,
|
showComments: true,
|
||||||
minimizeDescription: false,
|
minimizeDescription: false,
|
||||||
@ -347,7 +352,7 @@ export default {
|
|||||||
this.listen = this.getPreferenceBoolean("listen", false);
|
this.listen = this.getPreferenceBoolean("listen", false);
|
||||||
this.defaultQuality = Number(localStorage.getItem("quality"));
|
this.defaultQuality = Number(localStorage.getItem("quality"));
|
||||||
this.bufferingGoal = Math.max(Number(localStorage.getItem("bufferGoal")), 10);
|
this.bufferingGoal = Math.max(Number(localStorage.getItem("bufferGoal")), 10);
|
||||||
this.country = this.getPreferenceString("region", "US");
|
this.countrySelected = this.getPreferenceString("region", "US");
|
||||||
this.defaultHomepage = this.getPreferenceString("homepage", "trending");
|
this.defaultHomepage = this.getPreferenceString("homepage", "trending");
|
||||||
this.showComments = this.getPreferenceBoolean("comments", true);
|
this.showComments = this.getPreferenceBoolean("comments", true);
|
||||||
this.minimizeDescription = this.getPreferenceBoolean("minimizeDescription", false);
|
this.minimizeDescription = this.getPreferenceBoolean("minimizeDescription", false);
|
||||||
@ -400,7 +405,7 @@ export default {
|
|||||||
localStorage.setItem("listen", this.listen);
|
localStorage.setItem("listen", this.listen);
|
||||||
localStorage.setItem("quality", this.defaultQuality);
|
localStorage.setItem("quality", this.defaultQuality);
|
||||||
localStorage.setItem("bufferGoal", this.bufferingGoal);
|
localStorage.setItem("bufferGoal", this.bufferingGoal);
|
||||||
localStorage.setItem("region", this.country);
|
localStorage.setItem("region", this.countrySelected);
|
||||||
localStorage.setItem("homepage", this.defaultHomepage);
|
localStorage.setItem("homepage", this.defaultHomepage);
|
||||||
localStorage.setItem("comments", this.showComments);
|
localStorage.setItem("comments", this.showComments);
|
||||||
localStorage.setItem("minimizeDescription", this.minimizeDescription);
|
localStorage.setItem("minimizeDescription", this.minimizeDescription);
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
<form class="uk-panel uk-panel-box">
|
<form class="uk-panel uk-panel-box">
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<input
|
<input
|
||||||
|
v-model="username"
|
||||||
class="uk-width-1-1 uk-form-large uk-input uk-width-auto"
|
class="uk-width-1-1 uk-form-large uk-input uk-width-auto"
|
||||||
type="text"
|
type="text"
|
||||||
v-model="username"
|
|
||||||
autocomplete="username"
|
autocomplete="username"
|
||||||
:placeholder="$t('login.username')"
|
:placeholder="$t('login.username')"
|
||||||
:aria-label="$t('login.username')"
|
:aria-label="$t('login.username')"
|
||||||
@ -13,9 +13,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="uk-form-row">
|
<div class="uk-form-row">
|
||||||
<input
|
<input
|
||||||
|
v-model="password"
|
||||||
class="uk-width-1-1 uk-form-large uk-input uk-width-auto"
|
class="uk-width-1-1 uk-form-large uk-input uk-width-auto"
|
||||||
type="password"
|
type="password"
|
||||||
v-model="password"
|
|
||||||
autocomplete="password"
|
autocomplete="password"
|
||||||
:placeholder="$t('login.password')"
|
:placeholder="$t('login.password')"
|
||||||
:aria-label="$t('login.password')"
|
:aria-label="$t('login.password')"
|
||||||
@ -26,7 +26,8 @@
|
|||||||
class="uk-width-1-1 uk-button uk-button-primary uk-button-large uk-width-auto"
|
class="uk-width-1-1 uk-button uk-button-primary uk-button-large uk-width-auto"
|
||||||
style="background: #222"
|
style="background: #222"
|
||||||
@click="register"
|
@click="register"
|
||||||
> {{ $t("titles.register") }}</a
|
>
|
||||||
|
{{ $t("titles.register") }}</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -3,16 +3,18 @@
|
|||||||
{{ $route.query.search_query }}
|
{{ $route.query.search_query }}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<label for="ddlSearchFilters"><b>{{ $t("actions.filter") }}: </b></label>
|
<label for="ddlSearchFilters"
|
||||||
|
><b>{{ $t("actions.filter") }}: </b></label
|
||||||
|
>
|
||||||
<select
|
<select
|
||||||
id="ddlSearchFilters"
|
id="ddlSearchFilters"
|
||||||
|
v-model="selectedFilter"
|
||||||
default="all"
|
default="all"
|
||||||
class="uk-select uk-width-auto"
|
class="uk-select uk-width-auto"
|
||||||
style="height: 100%"
|
style="height: 100%"
|
||||||
v-model="selectedFilter"
|
|
||||||
@change="updateResults()"
|
@change="updateResults()"
|
||||||
>
|
>
|
||||||
<option v-bind:key="filter" v-for="filter in availableFilters" v-bind:value="filter">
|
<option v-for="filter in availableFilters" :key="filter" :value="filter">
|
||||||
{{ filter.replace("_", " ") }}
|
{{ filter.replace("_", " ") }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@ -21,16 +23,16 @@
|
|||||||
|
|
||||||
<div v-if="results" class="uk-grid-xl" uk-grid="parallax: 0">
|
<div v-if="results" class="uk-grid-xl" uk-grid="parallax: 0">
|
||||||
<div
|
<div
|
||||||
|
v-for="result in results.items"
|
||||||
|
:key="result.url"
|
||||||
:style="[{ background: backgroundColor }]"
|
:style="[{ background: backgroundColor }]"
|
||||||
class="uk-width-1-2 uk-width-1-3@s uk-width-1-4@m uk-width-1-5@l uk-width-1-6@xl"
|
class="uk-width-1-2 uk-width-1-3@s uk-width-1-4@m uk-width-1-5@l uk-width-1-6@xl"
|
||||||
v-bind:key="result.url"
|
|
||||||
v-for="result in results.items"
|
|
||||||
>
|
>
|
||||||
<VideoItem v-if="shouldUseVideoItem(result)" :video="result" height="94" width="168" />
|
<VideoItem v-if="shouldUseVideoItem(result)" :video="result" height="94" width="168" />
|
||||||
<div class="uk-text-secondary" v-if="!shouldUseVideoItem(result)">
|
<div v-if="!shouldUseVideoItem(result)" class="uk-text-secondary">
|
||||||
<router-link class="uk-text-emphasis" v-bind:to="result.url">
|
<router-link class="uk-text-emphasis" :to="result.url">
|
||||||
<div class="uk-position-relative">
|
<div class="uk-position-relative">
|
||||||
<img style="width: 100%" v-bind:src="result.thumbnail" loading="lazy" />
|
<img style="width: 100%" :src="result.thumbnail" loading="lazy" />
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
{{ result.name }} <font-awesome-icon
|
{{ result.name }} <font-awesome-icon
|
||||||
@ -40,7 +42,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</router-link>
|
</router-link>
|
||||||
<p v-if="result.description">{{ result.description }}</p>
|
<p v-if="result.description">{{ result.description }}</p>
|
||||||
<router-link class="uk-link-muted" v-if="result.uploaderUrl" v-bind:to="result.uploaderUrl">
|
<router-link v-if="result.uploaderUrl" class="uk-link-muted" :to="result.uploaderUrl">
|
||||||
<p>
|
<p>
|
||||||
{{ result.uploader }} <font-awesome-icon
|
{{ result.uploader }} <font-awesome-icon
|
||||||
v-if="result.uploaderVerified"
|
v-if="result.uploaderVerified"
|
||||||
@ -64,6 +66,9 @@
|
|||||||
import VideoItem from "@/components/VideoItem.vue";
|
import VideoItem from "@/components/VideoItem.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VideoItem,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
results: null,
|
results: null,
|
||||||
@ -123,8 +128,5 @@ export default {
|
|||||||
return item.title;
|
return item.title;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
VideoItem,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
v-for="(suggestion, i) in searchSuggestions"
|
v-for="(suggestion, i) in searchSuggestions"
|
||||||
:key="i"
|
:key="i"
|
||||||
:style="[selected === i ? { background: secondaryForegroundColor } : {}]"
|
:style="[selected === i ? { background: secondaryForegroundColor } : {}]"
|
||||||
|
class="uk-margin-remove suggestion"
|
||||||
@mouseover="onMouseOver(i)"
|
@mouseover="onMouseOver(i)"
|
||||||
@mousedown.stop="onClick(i)"
|
@mousedown.stop="onClick(i)"
|
||||||
class="uk-margin-remove suggestion"
|
|
||||||
>
|
>
|
||||||
{{ suggestion }}
|
{{ suggestion }}
|
||||||
</li>
|
</li>
|
||||||
@ -21,8 +21,9 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
searchText: String,
|
searchText: { type: String, default: "" },
|
||||||
},
|
},
|
||||||
|
emits: ["searchchange"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selected: 0,
|
selected: 0,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<h1 class="uk-text-bold uk-text-center">{{ $t("titles.subscriptions") }}</h1>
|
<h1 class="uk-text-bold uk-text-center">{{ $t("titles.subscriptions") }}</h1>
|
||||||
|
|
||||||
|
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
<button
|
<button
|
||||||
v-if="authenticated"
|
v-if="authenticated"
|
||||||
@ -16,35 +15,37 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="authenticated"
|
v-if="authenticated"
|
||||||
@click="exportHandler"
|
|
||||||
class="uk-button uk-button-small"
|
class="uk-button uk-button-small"
|
||||||
style="background: #222; color: white"
|
style="background: #222; color: white"
|
||||||
type="button"
|
type="button"
|
||||||
|
@click="exportHandler"
|
||||||
>
|
>
|
||||||
{{ $t("actions.export_to_json") }}
|
{{ $t("actions.export_to_json") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
<div v-for="subscription in subscriptions" :key="subscription.url" style="text-align: center;">
|
||||||
<div :key="subscription.url" v-for="subscription in subscriptions" style="text-align: center;">
|
<div class="uk-text-primary" :style="[{ background: backgroundColor }]">
|
||||||
<div class="uk-text-primary" :style="[{ background: backgroundColor }]">
|
<a :href="subscription.url">
|
||||||
<a :href="subscription.url">
|
<img :src="subscription.avatar" class="uk-margin-small-right uk-border-circle" width="96" height="96" />
|
||||||
<img :src="subscription.avatar" class="uk-margin-small-right uk-border-circle" width="96" height="96" />
|
<span
|
||||||
<span class="uk-text-large" style="width: 30rem; display: inline-block; text-align: center; margin-left: 6rem">{{ subscription.name }}</span>
|
class="uk-text-large"
|
||||||
</a>
|
style="width: 30rem; display: inline-block; text-align: center; margin-left: 6rem"
|
||||||
<button
|
>{{ subscription.name }}</span
|
||||||
class="uk-button uk-button-large"
|
|
||||||
style="background: #222; margin-left: 0.5rem; width: 185px"
|
|
||||||
type="button"
|
|
||||||
@click="handleButton(subscription)"
|
|
||||||
>
|
>
|
||||||
{{ subscription.subscribed ? $t("actions.unsubscribe") : $t("actions.subscribe") }}
|
</a>
|
||||||
</button>
|
<button
|
||||||
</div>
|
class="uk-button uk-button-large"
|
||||||
<br />
|
style="background: #222; margin-left: 0.5rem; width: 185px"
|
||||||
|
type="button"
|
||||||
|
@click="handleButton(subscription)"
|
||||||
|
>
|
||||||
|
{{ subscription.subscribed ? $t("actions.unsubscribe") : $t("actions.subscribe") }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
<br />
|
<br />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<h1 class="uk-text-bold uk-text-center" v-t="'titles.trending'" />
|
<h1 v-t="'titles.trending'" class="uk-text-bold uk-text-center" />
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
<div class="uk-grid-xl" uk-grid="parallax: 0">
|
||||||
<div
|
<div
|
||||||
|
v-for="video in videos"
|
||||||
|
:key="video.url"
|
||||||
:style="[{ background: backgroundColor }]"
|
:style="[{ background: backgroundColor }]"
|
||||||
class="uk-width-1-2 uk-width-1-3@s uk-width-1-4@m uk-width-1-5@l uk-width-1-6@xl"
|
class="uk-width-1-2 uk-width-1-3@s uk-width-1-4@m uk-width-1-5@l uk-width-1-6@xl"
|
||||||
v-bind:key="video.url"
|
|
||||||
v-for="video in videos"
|
|
||||||
>
|
>
|
||||||
<VideoItem :video="video" height="118" width="210" />
|
<VideoItem :video="video" height="118" width="210" />
|
||||||
</div>
|
</div>
|
||||||
@ -19,6 +19,9 @@
|
|||||||
import VideoItem from "@/components/VideoItem.vue";
|
import VideoItem from "@/components/VideoItem.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
VideoItem,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
videos: [],
|
videos: [],
|
||||||
@ -43,8 +46,5 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
VideoItem,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,14 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="uk-text-secondary" :style="[{ background: backgroundColor }]">
|
<div class="uk-text-secondary" :style="[{ background: backgroundColor }]">
|
||||||
<router-link class="uk-text-emphasis" v-bind:to="video.url">
|
<router-link class="uk-text-emphasis" :to="video.url">
|
||||||
<img
|
<img :height="height" :width="width" style="width: 100%" :src="video.thumbnail" alt="" loading="lazy" />
|
||||||
:height="height"
|
|
||||||
:width="width"
|
|
||||||
style="width: 100%"
|
|
||||||
v-bind:src="video.thumbnail"
|
|
||||||
alt=""
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<div class="uk-position-relative">
|
<div class="uk-position-relative">
|
||||||
<span
|
<span
|
||||||
v-if="video.duration"
|
v-if="video.duration"
|
||||||
@ -92,10 +85,15 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
video: Object,
|
video: {
|
||||||
height: String,
|
type: Object,
|
||||||
width: String,
|
default: () => {
|
||||||
hideChannel: Boolean,
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
height: { type: String, default: "118" },
|
||||||
|
width: { type: String, default: "210" },
|
||||||
|
hideChannel: { type: Boolean, default: false },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 999" v-if="video && isEmbed">
|
<div v-if="video && isEmbed" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 999">
|
||||||
<Player
|
<Player
|
||||||
ref="videoPlayer"
|
ref="videoPlayer"
|
||||||
:video="video"
|
:video="video"
|
||||||
:sponsors="sponsors"
|
:sponsors="sponsors"
|
||||||
:selectedAutoPlay="false"
|
:selected-auto-play="false"
|
||||||
:selectedAutoLoop="selectedAutoLoop"
|
:selected-auto-loop="selectedAutoLoop"
|
||||||
:isEmbed="isEmbed"
|
:is-embed="isEmbed"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="uk-container uk-container-xlarge" v-if="video && !isEmbed">
|
<div v-if="video && !isEmbed" class="uk-container uk-container-xlarge">
|
||||||
<ErrorHandler v-if="video && video.error" :message="video.message" :error="video.error" />
|
<ErrorHandler v-if="video && video.error" :message="video.message" :error="video.error" />
|
||||||
|
|
||||||
<div v-show="!video.error">
|
<div v-show="!video.error">
|
||||||
@ -18,8 +18,8 @@
|
|||||||
ref="videoPlayer"
|
ref="videoPlayer"
|
||||||
:video="video"
|
:video="video"
|
||||||
:sponsors="sponsors"
|
:sponsors="sponsors"
|
||||||
:selectedAutoPlay="selectedAutoPlay"
|
:selected-auto-play="selectedAutoPlay"
|
||||||
:selectedAutoLoop="selectedAutoLoop"
|
:selected-auto-loop="selectedAutoLoop"
|
||||||
/>
|
/>
|
||||||
<div class="uk-text-bold uk-margin-small-top uk-text-large uk-text-emphasis uk-text-break">
|
<div class="uk-text-bold uk-margin-small-top uk-text-large uk-text-emphasis uk-text-break">
|
||||||
{{ video.title }}
|
{{ video.title }}
|
||||||
@ -65,16 +65,16 @@
|
|||||||
|
|
||||||
<div class="uk-flex uk-flex-middle uk-margin-small-top">
|
<div class="uk-flex uk-flex-middle uk-margin-small-top">
|
||||||
<img :src="video.uploaderAvatar" alt="" loading="lazy" class="uk-border-circle" />
|
<img :src="video.uploaderAvatar" alt="" loading="lazy" class="uk-border-circle" />
|
||||||
<router-link class="uk-link uk-margin-small-left" v-if="video.uploaderUrl" :to="video.uploaderUrl">
|
<router-link v-if="video.uploaderUrl" class="uk-link uk-margin-small-left" :to="video.uploaderUrl">
|
||||||
{{ video.uploader }} </router-link
|
{{ video.uploader }} </router-link
|
||||||
> <font-awesome-icon v-if="video.uploaderVerified" icon="check"></font-awesome-icon>
|
> <font-awesome-icon v-if="video.uploaderVerified" icon="check"></font-awesome-icon>
|
||||||
<div class="uk-flex-1"></div>
|
<div class="uk-flex-1"></div>
|
||||||
<button
|
<button
|
||||||
v-if="authenticated"
|
v-if="authenticated"
|
||||||
@click="subscribeHandler"
|
|
||||||
class="uk-button uk-button-small"
|
class="uk-button uk-button-small"
|
||||||
style="background: #222"
|
style="background: #222"
|
||||||
type="button"
|
type="button"
|
||||||
|
@click="subscribeHandler"
|
||||||
>
|
>
|
||||||
{{ subscribed ? $t("actions.unsubscribe") : $t("actions.subscribe") }}
|
{{ subscribed ? $t("actions.unsubscribe") : $t("actions.subscribe") }}
|
||||||
</button>
|
</button>
|
||||||
@ -85,7 +85,8 @@
|
|||||||
<a class="uk-button uk-button-small" style="background: #222" @click="showDesc = !showDesc">
|
<a class="uk-button uk-button-small" style="background: #222" @click="showDesc = !showDesc">
|
||||||
{{ showDesc ? $t("actions.minimize_description") : $t("actions.show_description") }}
|
{{ showDesc ? $t("actions.minimize_description") : $t("actions.show_description") }}
|
||||||
</a>
|
</a>
|
||||||
<p v-show="showDesc" :style="[{ colour: foregroundColor }]" v-html="video.description"></p>
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
|
<p v-show="showDesc" :style="[{ colour: foregroundColor }]" v-html="purifyHTML(video.description)"></p>
|
||||||
<div v-if="showDesc && sponsors && sponsors.segments">
|
<div v-if="showDesc && sponsors && sponsors.segments">
|
||||||
{{ $t("video.sponsor_segments") }}: {{ sponsors.segments.length }}
|
{{ $t("video.sponsor_segments") }}: {{ sponsors.segments.length }}
|
||||||
</div>
|
</div>
|
||||||
@ -98,10 +99,10 @@
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
id="chkAutoLoop"
|
id="chkAutoLoop"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="selectedAutoLoop"
|
v-model="selectedAutoLoop"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<label for="chkAutoPlay"
|
<label for="chkAutoPlay"
|
||||||
@ -109,27 +110,27 @@
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
id="chkAutoPlay"
|
id="chkAutoPlay"
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="selectedAutoPlay"
|
v-model="selectedAutoPlay"
|
||||||
@change="onChange($event)"
|
class="uk-checkbox"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div uk-grid>
|
<div uk-grid>
|
||||||
<div class="uk-width-4-5@xl uk-width-3-4@s uk-width-1" v-if="comments" ref="comments">
|
<div v-if="comments" ref="comments" class="uk-width-4-5@xl uk-width-3-4@s uk-width-1">
|
||||||
<div
|
<div
|
||||||
|
v-for="comment in comments.comments"
|
||||||
|
:key="comment.commentId"
|
||||||
class="uk-tile-default uk-align-left uk-width-expand"
|
class="uk-tile-default uk-align-left uk-width-expand"
|
||||||
:style="[{ background: backgroundColor }]"
|
:style="[{ background: backgroundColor }]"
|
||||||
v-bind:key="comment.commentId"
|
|
||||||
v-for="comment in comments.comments"
|
|
||||||
>
|
>
|
||||||
<Comment :comment="comment" :uploader="video.uploader" />
|
<Comment :comment="comment" :uploader="video.uploader" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="uk-width-1-5@xl uk-width-1-4@s uk-width-1 uk-flex-last@s uk-flex-first" v-if="video">
|
<div v-if="video" class="uk-width-1-5@xl uk-width-1-4@s uk-width-1 uk-flex-last@s uk-flex-first">
|
||||||
<a
|
<a
|
||||||
class="uk-button uk-button-small uk-margin-small-bottom uk-hidden@s"
|
class="uk-button uk-button-small uk-margin-small-bottom uk-hidden@s"
|
||||||
style="background: #222"
|
style="background: #222"
|
||||||
@ -138,11 +139,11 @@
|
|||||||
{{ showRecs ? $t("actions.minimize_recommendations") : $t("actions.show_recommendations") }}
|
{{ showRecs ? $t("actions.minimize_recommendations") : $t("actions.show_recommendations") }}
|
||||||
</a>
|
</a>
|
||||||
<div
|
<div
|
||||||
|
v-for="related in video.relatedStreams"
|
||||||
v-show="showRecs || !smallView"
|
v-show="showRecs || !smallView"
|
||||||
|
:key="related.url"
|
||||||
class="uk-tile-default uk-width-auto"
|
class="uk-tile-default uk-width-auto"
|
||||||
:style="[{ background: backgroundColor }]"
|
:style="[{ background: backgroundColor }]"
|
||||||
v-bind:key="related.url"
|
|
||||||
v-for="related in video.relatedStreams"
|
|
||||||
>
|
>
|
||||||
<VideoItem :video="related" height="94" width="168" />
|
<VideoItem :video="related" height="94" width="168" />
|
||||||
</div>
|
</div>
|
||||||
@ -160,6 +161,12 @@ import Comment from "@/components/Comment.vue";
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
|
components: {
|
||||||
|
Player,
|
||||||
|
VideoItem,
|
||||||
|
ErrorHandler,
|
||||||
|
Comment,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
const smallViewQuery = window.matchMedia("(max-width: 640px)");
|
const smallViewQuery = window.matchMedia("(max-width: 640px)");
|
||||||
return {
|
return {
|
||||||
@ -179,6 +186,26 @@ export default {
|
|||||||
smallView: smallViewQuery.matches,
|
smallView: smallViewQuery.matches,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
isListening(_this) {
|
||||||
|
return _this.getPreferenceBoolean("listen", false);
|
||||||
|
},
|
||||||
|
toggleListenUrl(_this) {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
url.searchParams.set("listen", _this.isListening ? "0" : "1");
|
||||||
|
return url.href;
|
||||||
|
},
|
||||||
|
isEmbed(_this) {
|
||||||
|
return String(_this.$route.path).indexOf("/embed/") == 0;
|
||||||
|
},
|
||||||
|
uploadDate(_this) {
|
||||||
|
return new Date(_this.video.uploadDate).toLocaleString(undefined, {
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getVideoData().then(() => {
|
this.getVideoData().then(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
@ -254,12 +281,10 @@ export default {
|
|||||||
this.channelId = this.video.uploaderUrl.split("/")[2];
|
this.channelId = this.video.uploaderUrl.split("/")[2];
|
||||||
if (!this.isEmbed) this.fetchSubscribedStatus();
|
if (!this.isEmbed) this.fetchSubscribedStatus();
|
||||||
|
|
||||||
this.video.description = this.purifyHTML(
|
this.video.description = this.video.description
|
||||||
this.video.description
|
.replaceAll("http://www.youtube.com", "")
|
||||||
.replaceAll("http://www.youtube.com", "")
|
.replaceAll("https://www.youtube.com", "")
|
||||||
.replaceAll("https://www.youtube.com", "")
|
.replaceAll("\n", "<br>");
|
||||||
.replaceAll("\n", "<br>"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -317,31 +342,5 @@ export default {
|
|||||||
return this.$route.query.v || this.$route.params.v;
|
return this.$route.query.v || this.$route.params.v;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
isListening(_this) {
|
|
||||||
return _this.getPreferenceBoolean("listen", false);
|
|
||||||
},
|
|
||||||
toggleListenUrl(_this) {
|
|
||||||
const url = new URL(window.location.href);
|
|
||||||
url.searchParams.set("listen", _this.isListening ? "0" : "1");
|
|
||||||
return url.href;
|
|
||||||
},
|
|
||||||
isEmbed(_this) {
|
|
||||||
return String(_this.$route.path).indexOf("/embed/") == 0;
|
|
||||||
},
|
|
||||||
uploadDate(_this) {
|
|
||||||
return new Date(_this.video.uploadDate).toLocaleString(undefined, {
|
|
||||||
month: "short",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Player,
|
|
||||||
VideoItem,
|
|
||||||
ErrorHandler,
|
|
||||||
Comment,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -241,5 +241,5 @@ const app = createApp(App);
|
|||||||
app.use(i18n);
|
app.use(i18n);
|
||||||
app.use(router);
|
app.use(router);
|
||||||
app.mixin(mixin);
|
app.mixin(mixin);
|
||||||
app.component("font-awesome-icon", FontAwesomeIcon);
|
app.component("FontAwesomeIcon", FontAwesomeIcon);
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
pwa: {
|
pwa: {
|
||||||
name: 'Piped',
|
name: "Piped",
|
||||||
themeColor: '#fa4b4b',
|
themeColor: "#fa4b4b",
|
||||||
msTileColor: '#000000',
|
msTileColor: "#000000",
|
||||||
appleMobileWebAppCapable: 'yes',
|
appleMobileWebAppCapable: "yes",
|
||||||
appleMobileWebAppStatusBarStyle: 'black',
|
appleMobileWebAppStatusBarStyle: "black",
|
||||||
workboxPluginMode: 'GenerateSW',
|
workboxPluginMode: "GenerateSW",
|
||||||
workboxOptions: {
|
workboxOptions: {
|
||||||
navigateFallback: 'index.html',
|
navigateFallback: "index.html",
|
||||||
skipWaiting: true,
|
skipWaiting: true,
|
||||||
importWorkboxFrom: 'local',
|
importWorkboxFrom: "local",
|
||||||
runtimeCaching: [{
|
runtimeCaching: [
|
||||||
urlPattern: /\.(?:png|svg|ico)$/,
|
{
|
||||||
handler: 'CacheFirst',
|
urlPattern: /\.(?:png|svg|ico)$/,
|
||||||
}],
|
handler: "CacheFirst",
|
||||||
}
|
},
|
||||||
}
|
],
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
24
yarn.lock
24
yarn.lock
@ -3727,6 +3727,11 @@ escape-string-regexp@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||||
|
|
||||||
|
eslint-config-prettier@^8.3.0:
|
||||||
|
version "8.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a"
|
||||||
|
integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==
|
||||||
|
|
||||||
eslint-loader@^2.2.1:
|
eslint-loader@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337"
|
resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-2.2.1.tgz#28b9c12da54057af0845e2a6112701a2f6bf8337"
|
||||||
@ -3738,6 +3743,13 @@ eslint-loader@^2.2.1:
|
|||||||
object-hash "^1.1.4"
|
object-hash "^1.1.4"
|
||||||
rimraf "^2.6.1"
|
rimraf "^2.6.1"
|
||||||
|
|
||||||
|
eslint-plugin-prettier@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz#8b99d1e4b8b24a762472b4567992023619cb98e0"
|
||||||
|
integrity sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==
|
||||||
|
dependencies:
|
||||||
|
prettier-linter-helpers "^1.0.0"
|
||||||
|
|
||||||
eslint-plugin-vue@^7.19.1:
|
eslint-plugin-vue@^7.19.1:
|
||||||
version "7.19.1"
|
version "7.19.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.19.1.tgz#435fb2ce712842a9530b28eacb883680e8eaa4f3"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-7.19.1.tgz#435fb2ce712842a9530b28eacb883680e8eaa4f3"
|
||||||
@ -4068,6 +4080,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
|||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||||
|
|
||||||
|
fast-diff@^1.1.2:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03"
|
||||||
|
integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==
|
||||||
|
|
||||||
fast-glob@^2.2.6:
|
fast-glob@^2.2.6:
|
||||||
version "2.2.7"
|
version "2.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d"
|
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d"
|
||||||
@ -7025,6 +7042,13 @@ prepend-http@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
|
||||||
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
|
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
|
||||||
|
|
||||||
|
prettier-linter-helpers@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b"
|
||||||
|
integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
|
||||||
|
dependencies:
|
||||||
|
fast-diff "^1.1.2"
|
||||||
|
|
||||||
prettier@^1.18.2:
|
prettier@^1.18.2:
|
||||||
version "1.19.1"
|
version "1.19.1"
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
||||||
|
Loading…
Reference in New Issue
Block a user