mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-11-15 12:48:22 +00:00
Update from Main
This commit is contained in:
parent
3444c96118
commit
fa9381a6d7
@ -36,6 +36,7 @@
|
||||
>
|
||||
<font-awesome-icon icon="rss" />
|
||||
</a>
|
||||
<WatchOnYouTubeButton :link="`https://youtube.com/channel/${this.channel.id}`" />
|
||||
<p>|</p>
|
||||
<button
|
||||
v-for="(tab, index) in tabs"
|
||||
@ -75,11 +76,13 @@
|
||||
<script>
|
||||
import ErrorHandler from "./ErrorHandler.vue";
|
||||
import ContentItem from "./ContentItem.vue";
|
||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ErrorHandler,
|
||||
ContentItem,
|
||||
WatchOnYouTubeButton,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -201,23 +204,23 @@ export default {
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.handleLocalSubscriptions(this.channel.id);
|
||||
if (!this.handleLocalSubscriptions(this.channel.id)) return;
|
||||
}
|
||||
this.subscribed = !this.subscribed;
|
||||
},
|
||||
getTranslatedTabName(tabName) {
|
||||
let translatedTabName = tabName;
|
||||
switch (tabName) {
|
||||
case "Livestreams":
|
||||
case "livestreams":
|
||||
translatedTabName = this.$t("titles.livestreams");
|
||||
break;
|
||||
case "Playlists":
|
||||
case "playlists":
|
||||
translatedTabName = this.$t("titles.playlists");
|
||||
break;
|
||||
case "Channels":
|
||||
case "channels":
|
||||
translatedTabName = this.$t("titles.channels");
|
||||
break;
|
||||
case "Shorts":
|
||||
case "shorts":
|
||||
translatedTabName = this.$t("video.shorts");
|
||||
break;
|
||||
default:
|
||||
|
@ -4,7 +4,7 @@
|
||||
<font-awesome-icon :icon="['fab', 'github']" />
|
||||
<span v-t="'actions.source_code'" />
|
||||
</a>
|
||||
<a href="https://piped-docs.kavin.rocks/" target="_blank">
|
||||
<a href="https://docs.piped.video/" target="_blank">
|
||||
<font-awesome-icon :icon="['fa', 'book']" />
|
||||
<span v-t="'actions.documentation'" />
|
||||
</a>
|
||||
|
@ -159,7 +159,11 @@ export default {
|
||||
: [...new Set((this.getLocalSubscriptions() ?? []).concat(newChannels))];
|
||||
// Sort for better cache hits
|
||||
subscriptions.sort();
|
||||
try {
|
||||
localStorage.setItem("localSubscriptions", JSON.stringify(subscriptions));
|
||||
} catch (e) {
|
||||
alert(this.$t("info.local_storage"));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -14,7 +14,7 @@
|
||||
<div>
|
||||
<strong v-text="`${playlist.videos} ${$t('video.videos')}`" />
|
||||
<br />
|
||||
<button class="btn mr-1" v-if="authenticated && !isPipedPlaylist" @click="clonePlaylist">
|
||||
<button class="btn mr-1 ml-2" v-if="authenticated && !isPipedPlaylist" @click="clonePlaylist">
|
||||
{{ $t("actions.clone_playlist") }}<font-awesome-icon class="ml-3" icon="clone" />
|
||||
</button>
|
||||
<button class="btn mr-1" @click="downloadPlaylistAsTxt">
|
||||
@ -23,6 +23,7 @@
|
||||
<a class="btn" :href="getRssUrl">
|
||||
<font-awesome-icon icon="rss" />
|
||||
</a>
|
||||
<WatchOnYouTubeButton :link="`https://www.youtube.com/playlist?list=${this.$route.query.list}`" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -47,11 +48,13 @@
|
||||
<script>
|
||||
import ErrorHandler from "./ErrorHandler.vue";
|
||||
import VideoItem from "./VideoItem.vue";
|
||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ErrorHandler,
|
||||
VideoItem,
|
||||
WatchOnYouTubeButton,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -137,7 +140,7 @@ export default {
|
||||
downloadPlaylistAsTxt() {
|
||||
var data = "";
|
||||
this.playlist.relatedStreams.forEach(element => {
|
||||
data += "https://piped.kavin.rocks" + element.url + "\n";
|
||||
data += "https://piped.video" + element.url + "\n";
|
||||
});
|
||||
this.download(data, this.playlist.name + ".txt", "text/plain");
|
||||
},
|
||||
|
@ -3,8 +3,18 @@
|
||||
|
||||
<hr />
|
||||
|
||||
<div v-if="authenticated">
|
||||
<button v-t="'actions.create_playlist'" class="btn" @click="createPlaylist" />
|
||||
<div>
|
||||
<div class="flex">
|
||||
<button v-t="'actions.create_playlist'" class="btn mr-2" @click="onCreatePlaylist" />
|
||||
<button
|
||||
v-if="this.playlists.length > 0"
|
||||
v-t="'actions.export_to_json'"
|
||||
class="btn"
|
||||
@click="exportPlaylists"
|
||||
/>
|
||||
<input id="fileSelector" ref="fileSelector" type="file" class="display-none" @change="importPlaylists" />
|
||||
<label for="fileSelector" v-t="'actions.import_from_json'" class="btn ml-2" role="button" />
|
||||
</div>
|
||||
|
||||
<div class="video-grid">
|
||||
<div v-for="playlist in playlists" :key="playlist.id" class="efy_trans_filter">
|
||||
@ -36,34 +46,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-center h-[65vh] flex flex-col justify-center items-center">
|
||||
<h1 v-t="'actions.not_logged_in'"></h1>
|
||||
<div class="flex mt-100 items-center children:(mx-30)">
|
||||
<button @click="showLoginModal = true" v-t="'titles.account'"></button>
|
||||
<a class="btn h-min!" href="/" v-t="'actions.back_to_home'"></a>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<LoginModal v-if="showLoginModal" @close="showLoginModal = !showLoginModal" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LoginModal from "./LoginModal.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LoginModal,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
playlists: [],
|
||||
showLoginModal: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.authenticated) this.fetchPlaylists();
|
||||
else this.showLoginModal = true;
|
||||
else this.$router.push("/login");
|
||||
},
|
||||
activated() {
|
||||
document.title = this.$t("titles.playlists") + " - Piped";
|
||||
@ -119,10 +113,16 @@ export default {
|
||||
else this.playlists = this.playlists.filter(playlist => playlist.id !== id);
|
||||
});
|
||||
},
|
||||
createPlaylist() {
|
||||
onCreatePlaylist() {
|
||||
const name = prompt(this.$t("actions.create_playlist"));
|
||||
if (name)
|
||||
this.fetchJson(this.authApiUrl() + "/user/playlists/create", null, {
|
||||
if (!name) return;
|
||||
this.createPlaylist(name).then(json => {
|
||||
if (json.error) alert(json.error);
|
||||
else this.fetchPlaylists();
|
||||
});
|
||||
},
|
||||
async createPlaylist(name) {
|
||||
let json = await this.fetchJson(this.authApiUrl() + "/user/playlists/create", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
@ -131,9 +131,71 @@ export default {
|
||||
Authorization: this.getAuthToken(),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).then(json => {
|
||||
if (json.error) alert(json.error);
|
||||
else this.fetchPlaylists();
|
||||
});
|
||||
return json;
|
||||
},
|
||||
async exportPlaylists() {
|
||||
if (!this.playlists) return;
|
||||
let json = {
|
||||
format: "Piped",
|
||||
version: 1,
|
||||
playlists: [],
|
||||
};
|
||||
let tasks = [];
|
||||
for (var i = 0; i < this.playlists.length; i++) {
|
||||
tasks.push(this.fetchPlaylistJson(this.playlists[i].id));
|
||||
}
|
||||
json.playlists = await Promise.all(tasks);
|
||||
this.download(JSON.stringify(json), "playlists.json", "application/json");
|
||||
},
|
||||
async fetchPlaylistJson(playlistId) {
|
||||
let playlist = await this.fetchJson(this.authApiUrl() + "/playlists/" + playlistId);
|
||||
let playlistJson = {
|
||||
name: playlist.name,
|
||||
// possible other types: history, watch later, ...
|
||||
type: "playlist",
|
||||
// as Invidious supports public and private playlists
|
||||
visibility: "private",
|
||||
// list of the videos, starting with "https://youtube.com" to clarify that those are YT videos
|
||||
videos: [],
|
||||
};
|
||||
for (var i = 0; i < playlist.relatedStreams.length; i++) {
|
||||
playlistJson.videos.push("https://youtube.com" + playlist.relatedStreams[i].url);
|
||||
}
|
||||
return playlistJson;
|
||||
},
|
||||
async importPlaylists() {
|
||||
const file = this.$refs.fileSelector.files[0];
|
||||
let text = await file.text();
|
||||
let playlists = JSON.parse(text).playlists;
|
||||
if (!playlists.length) {
|
||||
alert(this.$t("actions.no_valid_playlists"));
|
||||
return;
|
||||
}
|
||||
let tasks = [];
|
||||
for (var i = 0; i < playlists.length; i++) {
|
||||
tasks.push(this.createPlaylistWithVideos(playlists[i]));
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
window.location.reload();
|
||||
},
|
||||
async createPlaylistWithVideos(playlist) {
|
||||
let newPlaylist = await this.createPlaylist(playlist.name);
|
||||
console.log(newPlaylist);
|
||||
let videoIds = playlist.videos.map(url => url.substr(-11));
|
||||
await this.addVideosToPlaylist(newPlaylist.playlistId, videoIds);
|
||||
},
|
||||
async addVideosToPlaylist(playlistId, videoIds) {
|
||||
await this.fetchJson(this.authApiUrl() + "/user/playlists/add", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
playlistId: playlistId,
|
||||
videoIds: videoIds,
|
||||
}),
|
||||
headers: {
|
||||
Authorization: this.getAuthToken(),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
|
@ -192,6 +192,36 @@
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkMinimizeChapters">
|
||||
<strong v-t="'actions.minimize_chapters_default'" />
|
||||
<input
|
||||
id="chkMinimizeChapters"
|
||||
v-model="minimizeChapters"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkShowWatchOnYouTube">
|
||||
<strong v-t="'actions.show_watch_on_youtube'" />
|
||||
<input
|
||||
id="chkShowWatchOnYouTube"
|
||||
v-model="showWatchOnYouTube"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkStoreSearchHistory">
|
||||
<strong v-t="'actions.store_search_history'" />
|
||||
<input
|
||||
id="chkStoreSearchHistory"
|
||||
v-model="searchHistory"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkStoreWatchHistory">
|
||||
<strong v-t="'actions.store_watch_history'" />
|
||||
<input
|
||||
@ -202,6 +232,16 @@
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label v-if="watchHistory" class="pref" for="chkHideWatched">
|
||||
<strong v-t="'actions.hide_watched'" />
|
||||
<input
|
||||
id="chkHideWatched"
|
||||
v-model="hideWatched"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="ddlEnabledCodecs">
|
||||
<strong v-t="'actions.enabled_codecs'" />
|
||||
<select
|
||||
@ -419,6 +459,8 @@ export default {
|
||||
minimizeComments: false,
|
||||
minimizeDescription: false,
|
||||
minimizeRecommendations: false,
|
||||
minimizeChapters: false,
|
||||
showWatchOnYouTube: false,
|
||||
watchHistory: false,
|
||||
searchHistory: false,
|
||||
hideWatched: false,
|
||||
@ -444,6 +486,7 @@ export default {
|
||||
{ code: "hi", name: "हिंदी" },
|
||||
{ code: "id", name: "Indonesia" },
|
||||
{ code: "is", name: "Íslenska" },
|
||||
{ code: "kab", name: "Taqbaylit" },
|
||||
{ code: "hr", name: "Hrvatski" },
|
||||
{ code: "it", name: "Italiano" },
|
||||
{ code: "ja", name: "日本語" },
|
||||
@ -452,10 +495,12 @@ export default {
|
||||
{ code: "ml", name: "മലയാളം" },
|
||||
{ code: "nb_NO", name: "Norwegian Bokmål" },
|
||||
{ code: "nl", name: "Nederlands" },
|
||||
{ code: "or", name: "ଓଡ଼ିଆ" },
|
||||
{ code: "pl", name: "Polski" },
|
||||
{ code: "pt", name: "Português" },
|
||||
{ code: "pt_PT", name: "Português (Portugal)" },
|
||||
{ code: "pt_BR", name: "Português (Brasil)" },
|
||||
{ code: "ro", name: "Română" },
|
||||
{ code: "ru", name: "Русский" },
|
||||
{ code: "sr", name: "Српски" },
|
||||
{ code: "sv", name: "Svenska" },
|
||||
@ -555,9 +600,11 @@ export default {
|
||||
this.minimizeComments = this.getPreferenceBoolean("minimizeComments", false);
|
||||
this.minimizeDescription = this.getPreferenceBoolean("minimizeDescription", false);
|
||||
this.minimizeRecommendations = this.getPreferenceBoolean("minimizeRecommendations", false);
|
||||
this.minimizeChapters = this.getPreferenceBoolean("minimizeChapters", false);
|
||||
this.showWatchOnYouTube = this.getPreferenceBoolean("showWatchOnYouTube", false);
|
||||
this.watchHistory = this.getPreferenceBoolean("watchHistory", false);
|
||||
this.searchHistory = this.getPreferenceBoolean("searchHistory", false);
|
||||
this.selectedLanguage = this.getPreferenceString("hl", await this.defaultLangage);
|
||||
this.selectedLanguage = this.getPreferenceString("hl", await this.defaultLanguage);
|
||||
this.enabledCodecs = this.getPreferenceString("enabledCodecs", "vp9,avc").split(",");
|
||||
this.disableLBRY = this.getPreferenceBoolean("disableLBRY", false);
|
||||
this.proxyLBRY = this.getPreferenceBoolean("proxyLBRY", false);
|
||||
@ -581,8 +628,8 @@ export default {
|
||||
if (
|
||||
this.getPreferenceString("theme", "dark") !== this.selectedTheme ||
|
||||
this.getPreferenceBoolean("watchHistory", false) != this.watchHistory ||
|
||||
this.getPreferenceString("hl", await this.defaultLangage) !== this.selectedLanguage ||
|
||||
this.getPreferenceString("enabledCodecs", "av1,vp9,avc") !== this.enabledCodecs.join(",")
|
||||
this.getPreferenceString("hl", await this.defaultLanguage) !== this.selectedLanguage ||
|
||||
this.getPreferenceString("enabledCodecs", "vp9,avc") !== this.enabledCodecs.join(",")
|
||||
)
|
||||
shouldReload = true;
|
||||
|
||||
@ -614,6 +661,8 @@ export default {
|
||||
localStorage.setItem("minimizeComments", this.minimizeComments);
|
||||
localStorage.setItem("minimizeDescription", this.minimizeDescription);
|
||||
localStorage.setItem("minimizeRecommendations", this.minimizeRecommendations);
|
||||
localStorage.setItem("minimizeChapters", this.minimizeChapters);
|
||||
localStorage.setItem("showWatchOnYouTube", this.showWatchOnYouTube);
|
||||
localStorage.setItem("watchHistory", this.watchHistory);
|
||||
localStorage.setItem("searchHistory", this.searchHistory);
|
||||
if (!this.searchHistory) localStorage.removeItem("search_history");
|
||||
|
@ -66,8 +66,8 @@ export default {
|
||||
}
|
||||
},
|
||||
onChange() {
|
||||
this.setPreference("shareWithTimeCode", this.withTimeCode);
|
||||
this.setPreference("shareAsPipedLink", this.pipedLink);
|
||||
this.setPreference("shareWithTimeCode", this.withTimeCode, true);
|
||||
this.setPreference("shareAsPipedLink", this.pipedLink, true);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
@ -9,27 +9,38 @@
|
||||
<i18n-t keypath="subscriptions.subscribed_channels_count">{{ subscriptions.length }}</i18n-t>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<div class="grid">
|
||||
<div class="mb-3" v-for="subscription in subscriptions" :key="subscription.url">
|
||||
<div class="flex justify-center place-items-center">
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<!-- Subscriptions card list -->
|
||||
<div class="pp-subs-cards">
|
||||
<!-- channel info card -->
|
||||
<div efy_card class="pp-subs-card" v-for="subscription in subscriptions" :key="subscription.url">
|
||||
<router-link :to="subscription.url" class="pp-import-channel flex font-bold">
|
||||
<img :src="subscription.avatar" width="48" height="48" />
|
||||
<span class="mx-2" v-text="subscription.name" />
|
||||
</router-link>
|
||||
<!-- (un)subscribe btn -->
|
||||
<button
|
||||
class="btn w-min"
|
||||
@click="handleButton(subscription)"
|
||||
v-t="`actions.${subscription.subscribed ? 'unsubscribe' : 'subscribe'}`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.pp-subs-cards {
|
||||
display: grid;
|
||||
gap: var(--efy_gap);
|
||||
grid-template-columns: repeat(auto-fill, minmax(240rem, 1fr));
|
||||
}
|
||||
.pp-subs-card :is(a, span) {
|
||||
-webkit-text-fill-color: var(--efy_text) !important;
|
||||
}
|
||||
.pp-subs-card button {
|
||||
margin-bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
|
@ -17,6 +17,7 @@ export default {
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.$route.path == "/" && this.getPreferenceString("homepage", "trending") == "feed") return;
|
||||
let region = this.getPreferenceString("region", "US");
|
||||
|
||||
this.fetchTrending(region).then(videos => {
|
||||
|
@ -273,7 +273,11 @@ export default {
|
||||
).generate_dash_file_from_formats(streams, this.video.duration);
|
||||
|
||||
uri = "data:application/dash+xml;charset=utf-8;base64," + btoa(dash);
|
||||
} else uri = this.video.dash;
|
||||
} else {
|
||||
const url = new URL(this.video.dash);
|
||||
url.searchParams.set("rewrite", false);
|
||||
uri = url.toString();
|
||||
}
|
||||
mime = "application/dash+xml";
|
||||
} else if (lbry) {
|
||||
uri = lbry.url;
|
||||
@ -372,13 +376,13 @@ export default {
|
||||
});
|
||||
|
||||
videoEl.addEventListener("volumechange", () => {
|
||||
this.setPreference("volume", videoEl.volume);
|
||||
this.setPreference("volume", videoEl.volume, true);
|
||||
});
|
||||
|
||||
videoEl.addEventListener("ratechange", e => {
|
||||
const rate = videoEl.playbackRate;
|
||||
if (rate > 0 && !isNaN(videoEl.duration) && !isNaN(videoEl.duration - e.timeStamp / 1000))
|
||||
this.setPreference("rate", rate);
|
||||
this.setPreference("rate", rate, true);
|
||||
});
|
||||
|
||||
videoEl.addEventListener("ended", () => {
|
||||
@ -440,7 +444,14 @@ export default {
|
||||
|
||||
this.$ui = new shaka.ui.Overlay(localPlayer, this.$refs.container, videoEl);
|
||||
|
||||
const overflowMenuButtons = ["quality", "captions", "picture_in_picture", "playback_rate", "airplay"];
|
||||
const overflowMenuButtons = [
|
||||
"quality",
|
||||
"language",
|
||||
"captions",
|
||||
"picture_in_picture",
|
||||
"playback_rate",
|
||||
"airplay",
|
||||
];
|
||||
|
||||
if (this.isEmbed) {
|
||||
overflowMenuButtons.push("open_new_tab");
|
||||
@ -480,22 +491,40 @@ export default {
|
||||
if (qualityConds) this.$player.configure("abr.enabled", false);
|
||||
|
||||
player.load(uri, 0, mime).then(() => {
|
||||
const isSafari = window.navigator?.vendor?.includes("Apple");
|
||||
|
||||
if (!isSafari) {
|
||||
// Set the audio language
|
||||
const prefLang = this.getPreferenceString("hl", "en").substr(0, 2);
|
||||
var lang = "en";
|
||||
for (var l in player.getAudioLanguages()) {
|
||||
if (l == prefLang) {
|
||||
lang = l;
|
||||
return;
|
||||
}
|
||||
}
|
||||
player.selectAudioLanguage(lang);
|
||||
}
|
||||
|
||||
if (qualityConds) {
|
||||
var leastDiff = Number.MAX_VALUE;
|
||||
var bestStream = null;
|
||||
|
||||
var bestAudio = 0;
|
||||
|
||||
const tracks = player
|
||||
.getVariantTracks()
|
||||
.filter(track => track.language == lang || track.language == "und");
|
||||
|
||||
// Choose the best audio stream
|
||||
if (quality >= 480)
|
||||
player.getVariantTracks().forEach(track => {
|
||||
tracks.forEach(track => {
|
||||
const audioBandwidth = track.audioBandwidth;
|
||||
if (audioBandwidth > bestAudio) bestAudio = audioBandwidth;
|
||||
});
|
||||
|
||||
// Find best matching stream based on resolution and bitrate
|
||||
player
|
||||
.getVariantTracks()
|
||||
tracks
|
||||
.sort((a, b) => a.bandwidth - b.bandwidth)
|
||||
.forEach(stream => {
|
||||
if (stream.audioBandwidth < bestAudio) return;
|
||||
@ -706,6 +735,7 @@ html .shaka-range-element:focus {
|
||||
.material-icons-round,
|
||||
.shaka-current-time {
|
||||
-webkit-text-fill-color: #fff !important;
|
||||
filter: none !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.shaka-overflow-menu,
|
||||
|
24
src/components/WatchOnYouTubeButton.vue
Normal file
24
src/components/WatchOnYouTubeButton.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
link: String,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="this.getPreferenceBoolean('showWatchOnYouTube', false)">
|
||||
<a :href="link" class="pp-watch-onyt-btn btn" role="button" :title="$t('player.watch_on') + 'YouTube'">
|
||||
<font-awesome-icon class="mx-1.5" :icon="['fab', 'youtube']" />
|
||||
</a>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.pp-watch-onyt-btn {
|
||||
display: flex;
|
||||
margin-left: var(--efy_gap0);
|
||||
align-items: center;
|
||||
gap: 5rem;
|
||||
}
|
||||
</style>
|
@ -96,7 +96,8 @@
|
||||
>
|
||||
<font-awesome-icon icon="rss" />
|
||||
</a>
|
||||
<!-- watch on youtube button -->
|
||||
<WatchOnYouTubeButton :link="`https://youtu.be/${getVideoId()}`" />
|
||||
<!-- Share Dialog -->
|
||||
<button class="btn" @click="showShareModal = !showShareModal">
|
||||
<i18n-t class="lt-lg:hidden" keypath="actions.share" tag="strong"></i18n-t>
|
||||
<font-awesome-icon class="mx-1.5 ml-1" icon="fa-share" />
|
||||
@ -212,6 +213,7 @@ import ChaptersBar from "./ChaptersBar.vue";
|
||||
import PlaylistAddModal from "./PlaylistAddModal.vue";
|
||||
import ShareModal from "./ShareModal.vue";
|
||||
import PlaylistVideos from "./PlaylistVideos.vue";
|
||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
@ -224,6 +226,7 @@ export default {
|
||||
PlaylistAddModal,
|
||||
ShareModal,
|
||||
PlaylistVideos,
|
||||
WatchOnYouTubeButton,
|
||||
},
|
||||
data() {
|
||||
const smallViewQuery = window.matchMedia("(max-width: 640px)");
|
||||
@ -330,6 +333,7 @@ export default {
|
||||
this.showComments = !this.getPreferenceBoolean("minimizeComments", false);
|
||||
this.showDesc = !this.getPreferenceBoolean("minimizeDescription", false);
|
||||
this.showRecs = !this.getPreferenceBoolean("minimizeRecommendations", false);
|
||||
this.showChapters = !this.getPreferenceBoolean("minimizeChapters", false);
|
||||
if (this.video.duration) {
|
||||
document.title = this.video.title + " - Piped";
|
||||
this.$refs.videoPlayer.loadVideo();
|
||||
@ -368,7 +372,7 @@ export default {
|
||||
return this.fetchJson(this.apiUrl() + "/comments/" + this.getVideoId());
|
||||
},
|
||||
onChange() {
|
||||
this.setPreference("autoplay", this.selectedAutoPlay);
|
||||
this.setPreference("autoplay", this.selectedAutoPlay, true);
|
||||
},
|
||||
async getVideoData() {
|
||||
await this.fetchVideo()
|
||||
@ -470,7 +474,7 @@ export default {
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.handleLocalSubscriptions(this.channelId);
|
||||
if (!this.handleLocalSubscriptions(this.channelId)) return;
|
||||
}
|
||||
this.subscribed = !this.subscribed;
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user