mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-08-14 23:57:27 +00:00
Merge fbe58aee7f
into d876f29f79
This commit is contained in:
commit
9c6915e4c7
5 changed files with 150 additions and 13 deletions
|
@ -45,6 +45,42 @@
|
||||||
@change="onChange($event)"
|
@change="onChange($event)"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
<details v-bind:class="{ details: autoPlayNextVideo }" open>
|
||||||
|
<summary class="pref">
|
||||||
|
<label class="w-full flex items-center justify-between" for="chkAutoPlayNextVideo">
|
||||||
|
<strong v-t="'actions.auto_play_next_video'" />
|
||||||
|
<input
|
||||||
|
id="chkAutoPlayNextVideo"
|
||||||
|
v-model="autoPlayNextVideo"
|
||||||
|
class="checkbox"
|
||||||
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</summary>
|
||||||
|
<div class="pl-4">
|
||||||
|
<label v-if="autoPlayNextVideo" class="pref" for="chkAutoPlayPreferUnwatched">
|
||||||
|
<strong v-t="'actions.autoplay_prefer_unwatched'" />
|
||||||
|
<input
|
||||||
|
id="chkAutoPlayPreferUnwatched"
|
||||||
|
v-model="autoPlayPreferUnwatched"
|
||||||
|
class="checkbox"
|
||||||
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label v-if="autoPlayNextVideo" class="pref" for="chkAutoPlayPreferSameAuthor">
|
||||||
|
<strong v-t="'actions.autoplay_prefer_same_author'" />
|
||||||
|
<input
|
||||||
|
id="chkAutoPlayPreferSameAuthor"
|
||||||
|
v-model="autoPlayPreferSameAuthor"
|
||||||
|
class="checkbox"
|
||||||
|
type="checkbox"
|
||||||
|
@change="onChange($event)"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
<label class="pref" for="chkAudioOnly">
|
<label class="pref" for="chkAudioOnly">
|
||||||
<strong v-t="'actions.audio_only'" />
|
<strong v-t="'actions.audio_only'" />
|
||||||
<input id="chkAudioOnly" v-model="listen" class="checkbox" type="checkbox" @change="onChange($event)" />
|
<input id="chkAudioOnly" v-model="listen" class="checkbox" type="checkbox" @change="onChange($event)" />
|
||||||
|
@ -346,6 +382,9 @@ export default {
|
||||||
minSegmentLength: 0,
|
minSegmentLength: 0,
|
||||||
selectedTheme: "dark",
|
selectedTheme: "dark",
|
||||||
autoPlayVideo: true,
|
autoPlayVideo: true,
|
||||||
|
autoPlayNextVideo: true,
|
||||||
|
autoPlayPreferUnwatched: true,
|
||||||
|
autoPlayPreferSameAuthor: false,
|
||||||
listen: false,
|
listen: false,
|
||||||
resolutions: [144, 240, 360, 480, 720, 1080, 1440, 2160, 4320],
|
resolutions: [144, 240, 360, 480, 720, 1080, 1440, 2160, 4320],
|
||||||
defaultQuality: 0,
|
defaultQuality: 0,
|
||||||
|
@ -461,6 +500,9 @@ export default {
|
||||||
this.minSegmentLength = Math.max(this.getPreferenceNumber("minSegmentLength", 0), 0);
|
this.minSegmentLength = Math.max(this.getPreferenceNumber("minSegmentLength", 0), 0);
|
||||||
this.selectedTheme = this.getPreferenceString("theme", "dark");
|
this.selectedTheme = this.getPreferenceString("theme", "dark");
|
||||||
this.autoPlayVideo = this.getPreferenceBoolean("playerAutoPlay", true);
|
this.autoPlayVideo = this.getPreferenceBoolean("playerAutoPlay", true);
|
||||||
|
this.autoPlayNextVideo = this.getPreferenceBoolean("autoplay", true);
|
||||||
|
this.autoPlayPreferUnwatched = this.getPreferenceBoolean("autoPlayUnwatched", true);
|
||||||
|
this.autoPlayPreferSameAuthor = this.getPreferenceBoolean("autoPlaySameAuthor", false);
|
||||||
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);
|
||||||
|
@ -515,6 +557,9 @@ export default {
|
||||||
localStorage.setItem("minSegmentLength", this.minSegmentLength);
|
localStorage.setItem("minSegmentLength", this.minSegmentLength);
|
||||||
localStorage.setItem("theme", this.selectedTheme);
|
localStorage.setItem("theme", this.selectedTheme);
|
||||||
localStorage.setItem("playerAutoPlay", this.autoPlayVideo);
|
localStorage.setItem("playerAutoPlay", this.autoPlayVideo);
|
||||||
|
localStorage.setItem("autoplay", this.autoPlayNextVideo);
|
||||||
|
localStorage.setItem("autoPlayUnwatched", this.autoPlayPreferUnwatched);
|
||||||
|
localStorage.setItem("autoPlaySameAuthor", this.autoPlayPreferSameAuthor);
|
||||||
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);
|
||||||
|
@ -602,4 +647,23 @@ export default {
|
||||||
.pref {
|
.pref {
|
||||||
@apply flex justify-between items-center my-2 mx-[15vw] lt-md:mx-[2vw];
|
@apply flex justify-between items-center my-2 mx-[15vw] lt-md:mx-[2vw];
|
||||||
}
|
}
|
||||||
|
.details summary {
|
||||||
|
@apply pl-4 relative cursor-pointer;
|
||||||
|
}
|
||||||
|
.details summary:before {
|
||||||
|
content: "";
|
||||||
|
border-width: 0.4rem;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: transparent transparent transparent #fff;
|
||||||
|
position: absolute;
|
||||||
|
top: 0.4rem;
|
||||||
|
left: 0;
|
||||||
|
margin-right: 1rem;
|
||||||
|
transform: rotate(0);
|
||||||
|
transform-origin: 0.2rem 50%;
|
||||||
|
transition: 0.25s transform ease;
|
||||||
|
}
|
||||||
|
details[open] > summary:before {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -38,6 +38,12 @@ export default {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nextVideo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
playlist: {
|
playlist: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
|
@ -610,7 +616,8 @@ export default {
|
||||||
},
|
},
|
||||||
navigateNext() {
|
navigateNext() {
|
||||||
const params = this.$route.query;
|
const params = this.$route.query;
|
||||||
let url = this.playlist?.relatedStreams?.[this.index]?.url ?? this.video.relatedStreams[0].url;
|
const relatedUrl = this.nextVideo?.url ?? this.video.relatedStreams[0].url;
|
||||||
|
let url = this.playlist?.relatedStreams?.[this.index]?.url ?? relatedUrl;
|
||||||
const searchParams = new URLSearchParams();
|
const searchParams = new URLSearchParams();
|
||||||
for (var param in params)
|
for (var param in params)
|
||||||
switch (param) {
|
switch (param) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
<VideoPlayer
|
<VideoPlayer
|
||||||
ref="videoPlayer"
|
ref="videoPlayer"
|
||||||
:video="video"
|
:video="video"
|
||||||
|
:next-video="nextVideo"
|
||||||
:sponsors="sponsors"
|
:sponsors="sponsors"
|
||||||
:playlist="playlist"
|
:playlist="playlist"
|
||||||
:index="index"
|
:index="index"
|
||||||
|
@ -206,8 +207,12 @@
|
||||||
/>
|
/>
|
||||||
<hr v-show="showRecs" />
|
<hr v-show="showRecs" />
|
||||||
<div v-show="showRecs">
|
<div v-show="showRecs">
|
||||||
|
<div v-if="nextVideo" class="">
|
||||||
|
<p v-t="'video.next_up'" />
|
||||||
|
<VideoItem :key="nextVideo.url" :item="nextVideo" height="94" width="168" />
|
||||||
|
</div>
|
||||||
<ContentItem
|
<ContentItem
|
||||||
v-for="related in video.relatedStreams"
|
v-for="related in filteredRelatedStreams"
|
||||||
:key="related.url"
|
:key="related.url"
|
||||||
:item="related"
|
:item="related"
|
||||||
height="94"
|
height="94"
|
||||||
|
@ -230,6 +235,7 @@ import PlaylistAddModal from "./PlaylistAddModal.vue";
|
||||||
import ShareModal from "./ShareModal.vue";
|
import ShareModal from "./ShareModal.vue";
|
||||||
import PlaylistVideos from "./PlaylistVideos.vue";
|
import PlaylistVideos from "./PlaylistVideos.vue";
|
||||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||||
|
import VideoItem from "./VideoItem.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
|
@ -243,6 +249,7 @@ export default {
|
||||||
ShareModal,
|
ShareModal,
|
||||||
PlaylistVideos,
|
PlaylistVideos,
|
||||||
WatchOnYouTubeButton,
|
WatchOnYouTubeButton,
|
||||||
|
VideoItem,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const smallViewQuery = window.matchMedia("(max-width: 640px)");
|
const smallViewQuery = window.matchMedia("(max-width: 640px)");
|
||||||
|
@ -250,6 +257,7 @@ export default {
|
||||||
video: {
|
video: {
|
||||||
title: "Loading...",
|
title: "Loading...",
|
||||||
},
|
},
|
||||||
|
nextVideo: null,
|
||||||
playlistId: null,
|
playlistId: null,
|
||||||
playlist: null,
|
playlist: null,
|
||||||
index: null,
|
index: null,
|
||||||
|
@ -291,6 +299,15 @@ export default {
|
||||||
year: "numeric",
|
year: "numeric",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
filteredRelatedStreams: _this => {
|
||||||
|
return _this.video.relatedStreams?.filter(video => video.url !== _this.nextVideo?.url);
|
||||||
|
},
|
||||||
|
preferUnwatched: _this => {
|
||||||
|
return _this.getPreferenceBoolean("autoPlayUnwatched", true) && !_this.isEmbed;
|
||||||
|
},
|
||||||
|
preferAuthor: _this => {
|
||||||
|
return _this.getPreferenceBoolean("autoPlaySameAuthor", false) && !_this.isEmbed;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// check screen size
|
// check screen size
|
||||||
|
@ -425,7 +442,13 @@ export default {
|
||||||
});
|
});
|
||||||
xmlDoc.querySelectorAll("br").forEach(elem => (elem.outerHTML = "\n"));
|
xmlDoc.querySelectorAll("br").forEach(elem => (elem.outerHTML = "\n"));
|
||||||
this.video.description = this.rewriteDescription(xmlDoc.querySelector("body").innerHTML);
|
this.video.description = this.rewriteDescription(xmlDoc.querySelector("body").innerHTML);
|
||||||
this.updateWatched(this.video.relatedStreams);
|
this.updateWatched(this.video.relatedStreams).then(() => {
|
||||||
|
if (!this.isEmbed) {
|
||||||
|
if (!this.playlistId) {
|
||||||
|
this.setNextVideo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -560,6 +583,37 @@ export default {
|
||||||
onTimeUpdate(time) {
|
onTimeUpdate(time) {
|
||||||
this.currentTime = time;
|
this.currentTime = time;
|
||||||
},
|
},
|
||||||
|
setNextVideo() {
|
||||||
|
if (!this.preferUnwatched && !this.preferAuthor) {
|
||||||
|
this.nextVideo = this.video.relatedStreams[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this.preferUnwatched) {
|
||||||
|
this.nextVideo = this.video.relatedStreams.find(video => video.uploaderUrl === this.video.uploaderUrl);
|
||||||
|
if (!this.nextVideo) this.nextVideo = this.video.relatedStreams[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < this.video.relatedStreams.length; i++) {
|
||||||
|
let foundAuthorMatch = false;
|
||||||
|
const video = this.video.relatedStreams[i];
|
||||||
|
if (!video.watched) {
|
||||||
|
if (!this.preferAuthor) {
|
||||||
|
this.nextVideo = video;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (video.uploaderUrl === this.video.uploaderUrl) {
|
||||||
|
this.nextVideo = video;
|
||||||
|
foundAuthorMatch = true;
|
||||||
|
break;
|
||||||
|
} else if (!foundAuthorMatch) {
|
||||||
|
this.nextVideo = video;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.nextVideo) {
|
||||||
|
this.nextVideo = this.video.relatedStreams[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
"dark": "Dark",
|
"dark": "Dark",
|
||||||
"light": "Light",
|
"light": "Light",
|
||||||
"autoplay_video": "Autoplay Video",
|
"autoplay_video": "Autoplay Video",
|
||||||
|
"autoplay_prefer_unwatched": "Prefer unwatched videos",
|
||||||
|
"autoplay_prefer_same_author": "Prefer videos from the same author",
|
||||||
"audio_only": "Audio Only",
|
"audio_only": "Audio Only",
|
||||||
"default_quality": "Default Quality",
|
"default_quality": "Default Quality",
|
||||||
"buffering_goal": "Buffering Goal (in seconds)",
|
"buffering_goal": "Buffering Goal (in seconds)",
|
||||||
|
@ -158,7 +160,8 @@
|
||||||
"live": "{0} Live",
|
"live": "{0} Live",
|
||||||
"shorts": "Shorts",
|
"shorts": "Shorts",
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"category": "Category"
|
"category": "Category",
|
||||||
|
"next_up": "Next up:"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"did_you_mean": "Did you mean: {0}?",
|
"did_you_mean": "Did you mean: {0}?",
|
||||||
|
|
27
src/main.js
27
src/main.js
|
@ -208,15 +208,24 @@ const mixin = {
|
||||||
if (window.db && this.getPreferenceBoolean("watchHistory", false)) {
|
if (window.db && this.getPreferenceBoolean("watchHistory", false)) {
|
||||||
var tx = window.db.transaction("watch_history", "readonly");
|
var tx = window.db.transaction("watch_history", "readonly");
|
||||||
var store = tx.objectStore("watch_history");
|
var store = tx.objectStore("watch_history");
|
||||||
videos.map(async video => {
|
return Promise.all(
|
||||||
var request = store.get(video.url.substr(-11));
|
videos.map(
|
||||||
request.onsuccess = function (event) {
|
video =>
|
||||||
if (event.target.result) {
|
new Promise(resolve => {
|
||||||
video.watched = true;
|
var request = store.get(video.url.substr(-11));
|
||||||
video.currentTime = event.target.result.currentTime;
|
request.onsuccess = function (event) {
|
||||||
}
|
if (event.target.result) {
|
||||||
};
|
video.watched = true;
|
||||||
});
|
video.currentTime = event.target.result.currentTime;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
request.onerror = function () {
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getLocalSubscriptions() {
|
getLocalSubscriptions() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue