0
0
Fork 0
mirror of https://github.com/VueTubeApp/VueTube synced 2025-01-05 15:11:13 +00:00

feat: pagination, url handling, tracking

This commit is contained in:
Alex 2022-04-01 14:02:08 +13:00
parent 1db075c5ee
commit 6e565d66b7
9 changed files with 113 additions and 40 deletions

View file

@ -9,7 +9,6 @@
<a
@click="openExternal($rendererUtils.getNavigationEndpoints(text))"
:key="index"
class="link"
>{{ text.text }}</a
>
</template>
@ -17,7 +16,6 @@
<a
@click="openInternal($rendererUtils.getNavigationEndpoints(text))"
:key="index"
class="link"
>{{ text.text }}</a
>
</template>

View file

@ -0,0 +1,25 @@
<template>
<div class="observer" />
</template>
<script>
export default {
props: ["options"],
data: () => ({
observer: null,
}),
mounted() {
const options = this.options || {};
this.observer = new IntersectionObserver(([entry]) => {
if (entry && entry.isIntersecting) {
this.$emit("intersect");
}
}, options);
this.observer.observe(this.$el);
},
destroyed() {
this.observer.disconnect();
},
};
</script>

View file

@ -77,18 +77,20 @@ export default {
methods: {
refreshRecommendations() {
this.$emit("scroll-to-top");
const continuations = this.$store.state.recommendedVideos.continuations;
const continuations =
this.$store.state.recommendedVideos[
this.$store.state.recommendedVideos.length - 1
].continuations;
this.$store.commit("updateRecommendedVideos", []);
this.$youtube
.continuation(
continuations[1].reloadContinuationData.continuation,
.recommendContinuation(
continuations.find((element) => element.reloadContinuationData)
.reloadContinuationData.continuation,
"browse"
)
.then((result) => {
if (result)
this.$youtube.recommend(result).then((result) => {
if (result) this.$store.commit("updateRecommendedVideos", result);
});
console.log(result);
if (result) this.$store.commit("updateRecommendedVideos", [result]);
})
.catch((error) => this.$logger("Home Page (Nav Refresh)", error, true));
},

View file

@ -1,7 +1,10 @@
// this is an loading animation for videos
<template>
<center>
<v-skeleton-loader type="card-avatar, article, actions" />
<v-skeleton-loader type="card-avatar, article, actions" />
</center>
<div>
<v-skeleton-loader
v-for="i in 10"
:key="i"
type="image, list-item-avatar-two-line"
/>
</div>
</template>

View file

@ -124,6 +124,15 @@ export default {
window.history.back();
}
});
CapacitorApp.addListener("appUrlOpen", (event) => {
const slug = new URL(event.url);
// We only push to the route if there is a slug present
if (slug) {
console.log(slug.pathname + slug.search);
this.$router.push(slug.pathname + slug.search);
}
});
},
methods: {

View file

@ -7,16 +7,20 @@
<div>
<!-- Video Loading Animation -->
<vid-load-renderer v-if="!recommends.contents" />
<horizontal-list-renderer v-else :render="recommends.contents[0]" />
<vid-load-renderer v-if="recommends.length == 0" />
<div v-for="(section, index) in recommends" :key="index">
<horizontal-list-renderer :render="section.contents[0]" />
</div>
<observer @intersect="paginate" />
</div>
</template>
<script>
import horizontalListRenderer from "~/components/ListRenderers/horizontalListRenderer.vue";
import VidLoadRenderer from "~/components/vidLoadRenderer.vue";
import Observer from "~/components/observer.vue";
export default {
components: { horizontalListRenderer, VidLoadRenderer },
components: { horizontalListRenderer, VidLoadRenderer, Observer },
computed: {
recommends: {
@ -29,12 +33,29 @@ export default {
},
},
methods: {
paginate() {
if (this.recommends) {
this.$youtube
.recommendContinuation(
this.recommends[this.recommends.length - 1].continuations.find(
(element) => element.nextContinuationData
).nextContinuationData.continuation,
"browse"
)
.then((result) => {
this.recommends.push(result);
});
}
},
},
mounted() {
if (!this.recommends.items || !this.recommends.items.length) {
if (!this.recommends.length) {
this.$youtube
.recommend()
.then((result) => {
if (result) this.recommends = result;
if (result) this.recommends = [result];
})
.catch((error) => this.$logger("Home Page", error, true));
}

View file

@ -97,19 +97,19 @@ class Innertube {
async getContinuationsAsync(continuation, type) {
let data = { context: this.context, continuation: continuation };
let url
let url;
switch (type) {
case "browse":
url = `${constants.URLS.YT_BASE_API}/browse?key=${this.key}`;
break
break;
case "search":
url = `${constants.URLS.YT_BASE_API}/search?key=${this.key}`;
break
break;
case "next":
url = `${constants.URLS.YT_BASE_API}/next?key=${this.key}`;
break
break;
default:
throw ("Invalid type")
throw "Invalid type";
}
const response = await Http.post({
@ -234,9 +234,11 @@ class Innertube {
response.data.output?.playabilityStatus?.status == ("ERROR" || undefined)
)
throw new Error(
`Could not get information for video: ${response.status_code ||
response.data.output?.playabilityStatus?.status
} - ${response.message || response.data.output?.playabilityStatus?.reason
`Could not get information for video: ${
response.status_code ||
response.data.output?.playabilityStatus?.status
} - ${
response.message || response.data.output?.playabilityStatus?.reason
}`
);
const responseInfo = response.data.output;

View file

@ -108,7 +108,6 @@ const innertubeModule = {
async recommend() {
const response = await InnertubeAPI.getRecommendationsAsync();
if (!response.success)
throw new Error("An error occurred and innertube failed to respond");
@ -120,30 +119,30 @@ const innertubeModule = {
if (video) return video;
});
const continuations = response.data.contents.singleColumnBrowseResultsRenderer.tabs[0]
.tabRenderer.content.sectionListRenderer.continuations
const continuations =
response.data.contents.singleColumnBrowseResultsRenderer.tabs[0]
.tabRenderer.content.sectionListRenderer.continuations;
console.log({ continuations: continuations, contents: final });
return { continuations: continuations, contents: final };
},
async recommendContinuation(response) {
const contents = response.continuationContents.sectionListContinuation.contents;
async recommendContinuation(continuation, endpoint) {
const response = await InnertubeAPI.getContinuationsAsync(
continuation,
endpoint
);
const contents =
response.data.continuationContents.sectionListContinuation.contents;
const final = contents.map((shelves) => {
const video = shelves.shelfRenderer?.content?.horizontalListRenderer;
if (video) return video;
});
const continuations = response.continuationContents.sectionListContinuation.continuations
const continuations =
response.data.continuationContents.sectionListContinuation.continuations;
return { continuations: continuations, contents: final };
},
async continuation(continuation, endpoint) {
const response = await InnertubeAPI.getContinuationsAsync(continuation, endpoint);
console.log(response)
if (!response.success) throw new Error("An error occurred and innertube failed to respond");
return response
},
async search(query) {
try {
const response = await InnertubeAPI.getSearchAsync(query);

View file

@ -21,7 +21,21 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LAUNCHER" />>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="youtu.be" />
<data android:host="m.youtube.com" />
<data android:host="youtube.com" />
<data android:host="www.youtube.com" />
<data android:pathPattern="/.*" />
</intent-filter>
</activity>