Migrate code to composition api.

This commit is contained in:
Kavin
2026-03-27 00:41:48 +05:30
parent 2448b8aa1d
commit fa5bbbd267
50 changed files with 4506 additions and 4418 deletions

View File

@@ -152,7 +152,9 @@
aria-label="RSS feed"
title="RSS feed"
role="button"
:href="`${apiUrl()}/feed/unauthenticated/rss?channels=${video.uploaderUrl.split('/')[2]}`"
:href="`${apiUrl()}/feed/unauthenticated/rss?channels=${
video.uploaderUrl.split('/')[2]
}`"
target="_blank"
class="btn flex items-center"
>
@@ -282,11 +284,11 @@
<button
v-if="!comments?.disabled"
class="btn mb-2"
@click="toggleComments"
@click="toggleCommentsVisibility"
v-text="
`${$t(showComments ? 'actions.minimize_comments' : 'actions.show_comments')} (${numberFormat(
comments?.commentCount,
)})`
`${$t(
showComments ? 'actions.minimize_comments' : 'actions.show_comments',
)} (${numberFormat(comments?.commentCount)})`
"
/>
</div>
@@ -297,7 +299,7 @@
<div v-else-if="comments.disabled" class="">
<p v-t="'comment.disabled'" class="mt-8 text-center"></p>
</div>
<div v-else ref="comments" class="">
<div v-else ref="commentsEl" class="">
<CommentItem
v-for="comment in comments.comments"
:key="comment.commentId"
@@ -346,7 +348,9 @@
</LoadingIndicatorPage>
</template>
<script>
<script setup>
import { ref, computed, onMounted, onActivated, onDeactivated, onUnmounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import VideoPlayer from "./VideoPlayer.vue";
import ContentItem from "./ContentItem.vue";
import ErrorHandler from "./ErrorHandler.vue";
@@ -360,413 +364,428 @@ import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
import ToastComponent from "./ToastComponent.vue";
import { parseTimeParam } from "@/utils/Misc";
import { purifyHTML, rewriteDescription } from "@/utils/HtmlUtils";
import { fetchJson, apiUrl } from "@/composables/useApi.js";
import {
getPreferenceBoolean,
getPreferenceNumber,
getPreferenceString,
getPreferenceJSON,
setPreference,
} from "@/composables/usePreferences.js";
import { numberFormat, addCommas } from "@/composables/useFormatting.js";
import {
fetchSubscriptionStatus,
toggleSubscriptionState,
fetchDeArrowContent,
} from "@/composables/useSubscriptions.js";
import { updateWatched } from "@/composables/useMisc.js";
import { getPlaylist } from "@/composables/usePlaylists.js";
export default {
name: "App",
components: {
VideoPlayer,
ContentItem,
ErrorHandler,
CommentItem,
ChaptersBar,
PlaylistAddModal,
ShareModal,
PlaylistVideos,
WatchOnButton,
LoadingIndicatorPage,
ToastComponent,
},
data() {
const smallViewQuery = window.matchMedia("(max-width: 640px)");
return {
video: null,
playlistId: null,
playlist: null,
index: null,
sponsors: null,
selectedAutoLoop: false,
selectedAutoPlay: null,
showComments: true,
showDesc: false,
showRecs: true,
showChapters: true,
comments: null,
subscribed: false,
channelId: null,
active: true,
smallViewQuery: smallViewQuery,
smallView: smallViewQuery.matches,
showModal: false,
showShareModal: false,
isMobile: true,
currentTime: 0,
shouldShowToast: false,
timeoutCounter: null,
counter: 0,
theaterMode: false,
};
},
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");
url.searchParams.set("t", Math.floor(this.currentTime));
return url.pathname + url.search;
},
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",
});
},
defaultCounter(_this) {
return _this.getPreferenceNumber("autoPlayNextCountdown", 5);
},
purifiedDescription() {
return purifyHTML(this.video.description);
},
youtubeVideoHref() {
let link = `https://youtu.be/${this.getVideoId()}?t=${Math.round(this.currentTime)}`;
if (this.playlistId) link += `&list=${this.playlistId}`;
return link;
},
},
mounted() {
// check screen size
this.isMobile = window.innerWidth < 1024;
// add an event listener to watch for screen size changes
window.addEventListener("resize", () => {
this.isMobile = window.innerWidth < 1024;
});
this.getVideoData().then(() => {
(async () => {
const videoId = this.getVideoId();
const instance = this;
if (window.db && this.getPreferenceBoolean("watchHistory", false) && !this.video.error) {
var tx = window.db.transaction("watch_history", "readwrite");
var store = tx.objectStore("watch_history");
var request = store.get(videoId);
request.onsuccess = function (event) {
var video = event.target.result;
if (video) {
video.watchedAt = Date.now();
} else {
video = {
videoId: videoId,
title: instance.video.title,
duration: instance.video.duration,
thumbnail: instance.video.thumbnailUrl,
uploaderUrl: instance.video.uploaderUrl,
uploaderName: instance.video.uploader,
watchedAt: Date.now(),
};
}
store.put(video);
};
}
})();
if (this.active) this.$refs.videoPlayer.loadVideo();
});
this.playlistId = this.$route.query.list;
this.index = Number(this.$route.query.index);
this.getPlaylistData();
this.getSponsors();
if (!this.isEmbed && this.showComments) this.getComments();
if (this.isEmbed) document.querySelector("html").style.overflow = "hidden";
window.addEventListener("click", this.handleClick);
window.addEventListener("resize", () => {
this.smallView = this.smallViewQuery.matches;
});
},
activated() {
this.active = true;
this.theaterMode = this.getPreferenceBoolean(
"theaterMode",
window.innerWidth < (window.innerHeight * 4) / 3 + 467, //if the video player is limited by width rather than height, then clear up some horizontal room
);
this.selectedAutoPlay = this.getPreferenceNumber("autoplay", 1);
this.showComments = !this.getPreferenceBoolean("minimizeComments", false);
this.showDesc = !this.getPreferenceBoolean("minimizeDescription", true);
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();
}
window.addEventListener("scroll", this.handleScroll);
},
deactivated() {
this.active = false;
window.removeEventListener("scroll", this.handleScroll);
this.dismiss();
},
unmounted() {
window.removeEventListener("scroll", this.handleScroll);
window.removeEventListener("click", this.handleClick);
this.dismiss();
},
methods: {
fetchVideo() {
return this.fetchJson(this.apiUrl() + "/streams/" + this.getVideoId());
},
async fetchSponsors() {
var selectedSkip = this.getPreferenceString(
"selectedSkip",
"sponsor,interaction,selfpromo,music_offtopic",
).split(",");
const skipOptions = this.getPreferenceJSON("skipOptions");
if (skipOptions !== undefined) {
selectedSkip = Object.keys(skipOptions).filter(
k => skipOptions[k] !== undefined && skipOptions[k] !== "no",
);
const route = useRoute();
const router = useRouter();
const smallViewQuery = window.matchMedia("(max-width: 640px)");
const videoPlayer = ref(null);
const commentsEl = ref(null);
const video = ref(null);
const playlistId = ref(null);
const playlist = ref(null);
const index = ref(null);
const sponsors = ref(null);
const selectedAutoLoop = ref(false);
const selectedAutoPlay = ref(null);
const showComments = ref(true);
const showDesc = ref(false);
const showRecs = ref(true);
const showChapters = ref(true);
const comments = ref(null);
const subscribed = ref(false);
const channelId = ref(null);
const active = ref(true);
const smallView = ref(smallViewQuery.matches);
const showModal = ref(false);
const showShareModal = ref(false);
const isMobile = ref(true);
const currentTime = ref(0);
const shouldShowToast = ref(false);
let timeoutCounter = null;
const counter = ref(0);
const theaterMode = ref(false);
let loading = false;
const isListening = computed(() => {
return getPreferenceBoolean("listen", false);
});
const toggleListenUrl = computed(() => {
const url = new URL(window.location.href);
url.searchParams.set("listen", isListening.value ? "0" : "1");
url.searchParams.set("t", Math.floor(currentTime.value));
return url.pathname + url.search;
});
const isEmbed = computed(() => {
return String(route.path).indexOf("/embed/") == 0;
});
const uploadDate = computed(() => {
return new Date(video.value.uploadDate).toLocaleString(undefined, {
month: "short",
day: "numeric",
year: "numeric",
});
});
const defaultCounter = computed(() => {
return getPreferenceNumber("autoPlayNextCountdown", 5);
});
const purifiedDescription = computed(() => {
return purifyHTML(video.value.description);
});
const youtubeVideoHref = computed(() => {
let link = `https://youtu.be/${getVideoId()}?t=${Math.round(currentTime.value)}`;
if (playlistId.value) link += `&list=${playlistId.value}`;
return link;
});
function fetchVideo() {
return fetchJson(apiUrl() + "/streams/" + getVideoId());
}
async function fetchSponsors() {
var selectedSkip = getPreferenceString("selectedSkip", "sponsor,interaction,selfpromo,music_offtopic").split(",");
const skipOptions = getPreferenceJSON("skipOptions");
if (skipOptions !== undefined) {
selectedSkip = Object.keys(skipOptions).filter(k => skipOptions[k] !== undefined && skipOptions[k] !== "no");
}
const sponsorsData = await fetchJson(apiUrl() + "/sponsors/" + getVideoId(), {
category: JSON.stringify(selectedSkip),
});
sponsorsData?.segments?.forEach(segment => {
const option = skipOptions?.[segment.category];
segment.autoskip = option === undefined || option === "auto";
});
const minSegmentLength = Math.max(getPreferenceNumber("minSegmentLength", 0), 0);
sponsorsData.segments = sponsorsData.segments?.filter(segment => {
const length = segment.segment[1] - segment.segment[0];
return length >= minSegmentLength;
});
return sponsorsData;
}
function toggleCommentsVisibility() {
showComments.value = !showComments.value;
if (showComments.value && comments.value === null) {
fetchCommentsData();
}
}
function fetchCommentsData() {
return fetchJson(apiUrl() + "/comments/" + getVideoId());
}
function onChange() {
setPreference("autoplay", selectedAutoPlay.value, true);
}
async function getVideoData() {
await fetchVideo()
.then(data => {
video.value = data;
video.value.id = getVideoId();
})
.then(() => {
if (!video.value.error) {
document.title = video.value.title + " - Piped";
channelId.value = video.value.uploaderUrl.split("/")[2];
if (!isEmbed.value) fetchSubscribedStatus();
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(video.value.description, "text/html");
xmlDoc.querySelectorAll("a").forEach(elem => {
if (!elem.innerText.match(/(?:[\d]{1,2}:)?(?:[\d]{1,2}):(?:[\d]{1,2})/))
elem.outerHTML = elem.getAttribute("href");
});
xmlDoc.querySelectorAll("br").forEach(elem => (elem.outerHTML = "\n"));
video.value.description = rewriteDescription(xmlDoc.querySelector("body").innerHTML);
updateWatched(video.value.relatedStreams);
fetchDeArrowContent(video.value.relatedStreams);
}
});
}
const sponsors = await this.fetchJson(this.apiUrl() + "/sponsors/" + this.getVideoId(), {
category: JSON.stringify(selectedSkip),
});
sponsors?.segments?.forEach(segment => {
const option = skipOptions?.[segment.category];
segment.autoskip = option === undefined || option === "auto";
});
const minSegmentLength = Math.max(this.getPreferenceNumber("minSegmentLength", 0), 0);
sponsors.segments = sponsors.segments?.filter(segment => {
const length = segment.segment[1] - segment.segment[0];
return length >= minSegmentLength;
});
return sponsors;
},
toggleComments() {
this.showComments = !this.showComments;
if (this.showComments && this.comments === null) {
this.fetchComments();
}
},
fetchComments() {
return this.fetchJson(this.apiUrl() + "/comments/" + this.getVideoId());
},
onChange() {
this.setPreference("autoplay", this.selectedAutoPlay, true);
},
async getVideoData() {
await this.fetchVideo()
.then(data => {
this.video = data;
this.video.id = this.getVideoId();
})
.then(() => {
if (!this.video.error) {
document.title = this.video.title + " - Piped";
this.channelId = this.video.uploaderUrl.split("/")[2];
if (!this.isEmbed) this.fetchSubscribedStatus();
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(this.video.description, "text/html");
xmlDoc.querySelectorAll("a").forEach(elem => {
if (!elem.innerText.match(/(?:[\d]{1,2}:)?(?:[\d]{1,2}):(?:[\d]{1,2})/))
elem.outerHTML = elem.getAttribute("href");
async function getPlaylistData() {
if (playlistId.value) {
playlist.value = await getPlaylist(playlistId.value);
await fetchPlaylistPages().then(() => {
if (!(index.value >= 0)) {
for (let i = 0; i < playlist.value.relatedStreams.length; i++)
if (playlist.value.relatedStreams[i].url.substr(-11) == getVideoId()) {
index.value = i + 1;
router.replace({
query: { ...route.query, index: index.value },
});
xmlDoc.querySelectorAll("br").forEach(elem => (elem.outerHTML = "\n"));
this.video.description = rewriteDescription(xmlDoc.querySelector("body").innerHTML);
this.updateWatched(this.video.relatedStreams);
this.fetchDeArrowContent(this.video.relatedStreams);
break;
}
});
},
async getPlaylistData() {
if (this.playlistId) {
this.playlist = await this.getPlaylist(this.playlistId);
await this.fetchPlaylistPages().then(() => {
if (!(this.index >= 0)) {
for (let i = 0; i < this.playlist.relatedStreams.length; i++)
if (this.playlist.relatedStreams[i].url.substr(-11) == this.getVideoId()) {
this.index = i + 1;
this.$router.replace({
query: { ...this.$route.query, index: this.index },
});
break;
}
}
});
await this.fetchPlaylistPages();
}
},
async fetchPlaylistPages() {
if (this.playlist.nextpage) {
await this.fetchJson(this.apiUrl() + "/nextpage/playlists/" + this.playlistId, {
nextpage: this.playlist.nextpage,
}).then(json => {
this.playlist.relatedStreams.push(...json.relatedStreams);
this.playlist.nextpage = json.nextpage;
this.fetchDeArrowContent(json.relatedStreams);
});
await this.fetchPlaylistPages();
}
},
async getSponsors() {
if (this.getPreferenceBoolean("sponsorblock", true))
this.fetchSponsors().then(data => (this.sponsors = data));
},
async getComments() {
this.comments = await this.fetchComments();
},
async fetchSubscribedStatus() {
if (!this.channelId) return;
});
await fetchPlaylistPages();
}
}
this.subscribed = await this.fetchSubscriptionStatus(this.channelId);
},
subscribeHandler() {
this.toggleSubscriptionState(this.channelId, this.subscribed).then(success => {
if (success) this.subscribed = !this.subscribed;
});
},
handleClick(event) {
if (!event || !event.target) return;
if (!event.target.matches("a[href]")) return;
const target = event.target;
if (!target.getAttribute("href")) return;
if (this.handleTimestampLinks(target)) {
event.preventDefault();
}
},
handleTimestampLinks(target) {
try {
const url = new URL(target.getAttribute("href"), document.baseURI);
if (
url.searchParams.size > 2 ||
url.searchParams.get("v") !== this.getVideoId() ||
!url.searchParams.has("t")
) {
return false;
}
const time = parseTimeParam(url.searchParams.get("t"));
if (time) {
this.navigate(time);
}
return true;
} catch (e) {
console.error(e);
}
async function fetchPlaylistPages() {
if (playlist.value.nextpage) {
await fetchJson(apiUrl() + "/nextpage/playlists/" + playlistId.value, {
nextpage: playlist.value.nextpage,
}).then(json => {
playlist.value.relatedStreams.push(...json.relatedStreams);
playlist.value.nextpage = json.nextpage;
fetchDeArrowContent(json.relatedStreams);
});
await fetchPlaylistPages();
}
}
async function getSponsors() {
if (getPreferenceBoolean("sponsorblock", true)) fetchSponsors().then(data => (sponsors.value = data));
}
async function getComments() {
comments.value = await fetchCommentsData();
}
async function fetchSubscribedStatus() {
if (!channelId.value) return;
subscribed.value = await fetchSubscriptionStatus(channelId.value);
}
function subscribeHandler() {
toggleSubscriptionState(channelId.value, subscribed.value).then(success => {
if (success) subscribed.value = !subscribed.value;
});
}
function handleClick(event) {
if (!event || !event.target) return;
if (!event.target.matches("a[href]")) return;
const target = event.target;
if (!target.getAttribute("href")) return;
if (handleTimestampLinks(target)) {
event.preventDefault();
}
}
function handleTimestampLinks(target) {
try {
const url = new URL(target.getAttribute("href"), document.baseURI);
if (url.searchParams.size > 2 || url.searchParams.get("v") !== getVideoId() || !url.searchParams.has("t")) {
return false;
},
handleScroll() {
if (this.loading || !this.comments || !this.comments.nextpage) return;
if (window.innerHeight + window.scrollY >= this.$refs.comments?.offsetHeight - window.innerHeight) {
this.loading = true;
this.fetchJson(this.apiUrl() + "/nextpage/comments/" + this.getVideoId(), {
nextpage: this.comments.nextpage,
}).then(json => {
this.comments.nextpage = json.nextpage;
this.loading = false;
this.comments.comments = this.comments.comments.concat(json.comments);
});
}
},
getVideoId() {
if (this.$route.query.video_ids) {
const videos_list = this.$route.query.video_ids.split(",");
this.index = Number(this.$route.query.index ?? 0);
return videos_list[this.index];
}
}
const time = parseTimeParam(url.searchParams.get("t"));
if (time) {
navigate(time);
}
return true;
} catch (e) {
console.error(e);
}
return false;
}
return this.$route.query.v || this.$route.params.v;
},
navigate(time) {
this.$refs.videoPlayer.seek(time);
},
onTimeUpdate(time) {
this.currentTime = time;
},
onVideoEnded() {
if (
!this.selectedAutoLoop &&
((this.selectedAutoPlay >= 1 && this.playlist?.relatedStreams?.length > this.index) ||
(this.selectedAutoPlay >= 2 && this.video.relatedStreams.length > 0))
) {
this.showToast();
}
},
showToast() {
this.counter = this.defaultCounter;
if (this.counter < 1) {
this.navigateNext();
return;
}
if (this.timeoutCounter) clearInterval(this.timeoutCounter);
this.timeoutCounter = setInterval(() => {
this.counter--;
if (this.counter === 0) {
this.dismiss();
this.navigateNext();
}
}, 1000);
this.shouldShowToast = true;
},
dismiss() {
clearInterval(this.timeoutCounter);
this.shouldShowToast = false;
},
navigateNext() {
const params = this.$route.query;
const video_ids = this.$route.query.video_ids?.split(",") ?? [];
let url;
if (this.playlist) {
url = this.playlist?.relatedStreams?.[this.index]?.url ?? this.video.relatedStreams[0].url;
} else if (video_ids.length > this.index + 1) {
url = `${this.$route.path}?index=${this.index + 1}`;
} else {
url = this.video.relatedStreams[0].url;
}
const searchParams = new URLSearchParams();
for (var param in params)
switch (param) {
case "v":
case "t":
break;
case "index":
if (this.playlist && this.index < this.playlist.relatedStreams.length)
searchParams.set("index", this.index + 1);
break;
case "list":
if (this.index < this.playlist.relatedStreams.length) searchParams.set("list", params.list);
break;
default:
searchParams.set(param, params[param]);
break;
}
// save the fullscreen state
searchParams.set("fullscreen", this.$refs.videoPlayer.$ui.getControls().isFullScreenEnabled());
const paramStr = searchParams.toString();
if (paramStr.length > 0) url += "&" + paramStr;
this.$router.push(url);
},
downloadCurrentFrame() {
const video = document.querySelector("video");
const canvas = document.createElement("canvas");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
function handleScroll() {
if (loading || !comments.value || !comments.value.nextpage) return;
if (window.innerHeight + window.scrollY >= commentsEl.value?.offsetHeight - window.innerHeight) {
loading = true;
fetchJson(apiUrl() + "/nextpage/comments/" + getVideoId(), {
nextpage: comments.value.nextpage,
}).then(json => {
comments.value.nextpage = json.nextpage;
loading = false;
comments.value.comments = comments.value.comments.concat(json.comments);
});
}
}
const context = canvas.getContext("2d");
context.drawImage(video, 0, 0, canvas.width, canvas.height);
function getVideoId() {
if (route.query.video_ids) {
const videos_list = route.query.video_ids.split(",");
index.value = Number(route.query.index ?? 0);
return videos_list[index.value];
}
let link = document.createElement("a");
const currentTime = Math.round(video.currentTime * 1000) / 1000;
link.download = `${this.video.title}_${currentTime}s.png`;
link.href = canvas.toDataURL();
link.click();
},
},
};
return route.query.v || route.params.v;
}
function navigate(time) {
videoPlayer.value.seek(time);
}
function onTimeUpdate(time) {
currentTime.value = time;
}
function onVideoEnded() {
if (
!selectedAutoLoop.value &&
((selectedAutoPlay.value >= 1 && playlist.value?.relatedStreams?.length > index.value) ||
(selectedAutoPlay.value >= 2 && video.value.relatedStreams.length > 0))
) {
showToast();
}
}
function showToast() {
counter.value = defaultCounter.value;
if (counter.value < 1) {
navigateNext();
return;
}
if (timeoutCounter) clearInterval(timeoutCounter);
timeoutCounter = setInterval(() => {
counter.value--;
if (counter.value === 0) {
dismiss();
navigateNext();
}
}, 1000);
shouldShowToast.value = true;
}
function dismiss() {
clearInterval(timeoutCounter);
shouldShowToast.value = false;
}
function navigateNext() {
const params = route.query;
const video_ids = route.query.video_ids?.split(",") ?? [];
let url;
if (playlist.value) {
url = playlist.value?.relatedStreams?.[index.value]?.url ?? video.value.relatedStreams[0].url;
} else if (video_ids.length > index.value + 1) {
url = `${route.path}?index=${index.value + 1}`;
} else {
url = video.value.relatedStreams[0].url;
}
const searchParams = new URLSearchParams();
for (var param in params)
switch (param) {
case "v":
case "t":
break;
case "index":
if (playlist.value && index.value < playlist.value.relatedStreams.length)
searchParams.set("index", index.value + 1);
break;
case "list":
if (index.value < playlist.value.relatedStreams.length) searchParams.set("list", params.list);
break;
default:
searchParams.set(param, params[param]);
break;
}
searchParams.set("fullscreen", videoPlayer.value.isFullScreenEnabled());
const paramStr = searchParams.toString();
if (paramStr.length > 0) url += "&" + paramStr;
router.push(url);
}
function downloadCurrentFrame() {
const videoEl = document.querySelector("video");
const canvas = document.createElement("canvas");
canvas.width = videoEl.videoWidth;
canvas.height = videoEl.videoHeight;
const context = canvas.getContext("2d");
context.drawImage(videoEl, 0, 0, canvas.width, canvas.height);
let link = document.createElement("a");
const ct = Math.round(videoEl.currentTime * 1000) / 1000;
link.download = `${video.value.title}_${ct}s.png`;
link.href = canvas.toDataURL();
link.click();
}
onMounted(() => {
isMobile.value = window.innerWidth < 1024;
window.addEventListener("resize", () => {
isMobile.value = window.innerWidth < 1024;
});
getVideoData().then(() => {
(async () => {
const videoId = getVideoId();
if (window.db && getPreferenceBoolean("watchHistory", false) && !video.value.error) {
var tx = window.db.transaction("watch_history", "readwrite");
var store = tx.objectStore("watch_history");
var request = store.get(videoId);
request.onsuccess = function (event) {
var vid = event.target.result;
if (vid) {
vid.watchedAt = Date.now();
} else {
vid = {
videoId: videoId,
title: video.value.title,
duration: video.value.duration,
thumbnail: video.value.thumbnailUrl,
uploaderUrl: video.value.uploaderUrl,
uploaderName: video.value.uploader,
watchedAt: Date.now(),
};
}
store.put(vid);
};
}
})();
if (active.value) videoPlayer.value.loadVideo();
});
playlistId.value = route.query.list;
index.value = Number(route.query.index);
getPlaylistData();
getSponsors();
if (!isEmbed.value && showComments.value) getComments();
if (isEmbed.value) document.querySelector("html").style.overflow = "hidden";
window.addEventListener("click", handleClick);
window.addEventListener("resize", () => {
smallView.value = smallViewQuery.matches;
});
});
onActivated(() => {
active.value = true;
theaterMode.value = getPreferenceBoolean("theaterMode", window.innerWidth < (window.innerHeight * 4) / 3 + 467);
selectedAutoPlay.value = getPreferenceNumber("autoplay", 1);
showComments.value = !getPreferenceBoolean("minimizeComments", false);
showDesc.value = !getPreferenceBoolean("minimizeDescription", true);
showRecs.value = !getPreferenceBoolean("minimizeRecommendations", false);
showChapters.value = !getPreferenceBoolean("minimizeChapters", false);
if (video.value?.duration) {
document.title = video.value.title + " - Piped";
videoPlayer.value.loadVideo();
}
window.addEventListener("scroll", handleScroll);
});
onDeactivated(() => {
active.value = false;
window.removeEventListener("scroll", handleScroll);
dismiss();
});
onUnmounted(() => {
window.removeEventListener("scroll", handleScroll);
window.removeEventListener("click", handleClick);
dismiss();
});
</script>
<style>