mirror of
				https://github.com/TeamPiped/Piped.git
				synced 2024-08-14 23:57:27 +00:00 
			
		
		
		
	Merge pull request #3346 from Bnyro/subscribe-channel-on-fly
feat: support for subscribing to channels in search results
This commit is contained in:
		
						commit
						1dd1f83b1a
					
				
					 4 changed files with 96 additions and 82 deletions
				
			
		| 
						 | 
					@ -1,37 +1,72 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div class="flex flex-col flex-justify-between">
 | 
					    <div class="flex flex-col flex-justify-between">
 | 
				
			||||||
        <router-link :to="props.item.url">
 | 
					        <router-link :to="item.url">
 | 
				
			||||||
            <div class="my-4 flex justify-center">
 | 
					            <div class="my-4 flex justify-center">
 | 
				
			||||||
                <img loading="lazy" class="aspect-square w-[50%] rounded-full" :src="props.item.thumbnail" />
 | 
					                <img loading="lazy" class="aspect-square w-[50%] rounded-full" :src="item.thumbnail" />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <p>
 | 
					            <p>
 | 
				
			||||||
                <span v-text="props.item.name" />
 | 
					                <span v-text="item.name" />
 | 
				
			||||||
                <font-awesome-icon v-if="props.item.verified" class="ml-1.5" icon="check" />
 | 
					                <font-awesome-icon v-if="item.verified" class="ml-1.5" icon="check" />
 | 
				
			||||||
            </p>
 | 
					            </p>
 | 
				
			||||||
        </router-link>
 | 
					        </router-link>
 | 
				
			||||||
        <p v-if="props.item.description" v-text="props.item.description" />
 | 
					        <p v-if="item.description" v-text="item.description" />
 | 
				
			||||||
        <router-link v-if="props.item.uploaderUrl" class="link" :to="props.item.uploaderUrl">
 | 
					        <router-link v-if="item.uploaderUrl" class="link" :to="item.uploaderUrl">
 | 
				
			||||||
            <p>
 | 
					            <p>
 | 
				
			||||||
                <span v-text="props.item.uploader" />
 | 
					                <span v-text="item.uploader" />
 | 
				
			||||||
                <font-awesome-icon v-if="props.item.uploaderVerified" class="ml-1.5" icon="check" />
 | 
					                <font-awesome-icon v-if="item.uploaderVerified" class="ml-1.5" icon="check" />
 | 
				
			||||||
            </p>
 | 
					            </p>
 | 
				
			||||||
        </router-link>
 | 
					        </router-link>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <a v-if="props.item.uploaderName" class="link" v-text="props.item.uploaderName" />
 | 
					        <a v-if="item.uploaderName" class="link" v-text="item.uploaderName" />
 | 
				
			||||||
        <template v-if="props.item.videos >= 0">
 | 
					        <template v-if="item.videos >= 0">
 | 
				
			||||||
            <br v-if="props.item.uploaderName" />
 | 
					            <br v-if="item.uploaderName" />
 | 
				
			||||||
            <strong v-text="`${props.item.videos} ${$t('video.videos')}`" />
 | 
					            <strong v-text="`${item.videos} ${$t('video.videos')}`" />
 | 
				
			||||||
        </template>
 | 
					        </template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <button
 | 
				
			||||||
 | 
					            v-if="subscribed != null"
 | 
				
			||||||
 | 
					            class="btn w-max mt-2"
 | 
				
			||||||
 | 
					            @click="subscribeHandler"
 | 
				
			||||||
 | 
					            v-text="
 | 
				
			||||||
 | 
					                $t('actions.' + (subscribed ? 'unsubscribe' : 'subscribe')) + ' - ' + numberFormat(item.subscribers)
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <br />
 | 
					        <br />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup>
 | 
					<script>
 | 
				
			||||||
const props = defineProps({
 | 
					export default {
 | 
				
			||||||
    item: {
 | 
					    props: {
 | 
				
			||||||
        type: Object,
 | 
					        item: {
 | 
				
			||||||
        required: true,
 | 
					            type: Object,
 | 
				
			||||||
 | 
					            required: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
});
 | 
					    data() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            subscribed: null,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    computed: {
 | 
				
			||||||
 | 
					        channelId(_this) {
 | 
				
			||||||
 | 
					            return _this.item.url.substr(-24);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    mounted() {
 | 
				
			||||||
 | 
					        this.updateSubscribedStatus();
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					        async updateSubscribedStatus() {
 | 
				
			||||||
 | 
					            this.subscribed = await this.fetchSubscriptionStatus(this.channelId);
 | 
				
			||||||
 | 
					            console.log(this.subscribed);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        subscribeHandler() {
 | 
				
			||||||
 | 
					            this.toggleSubscriptionState(this.channelId, this.subscribed).then(success => {
 | 
				
			||||||
 | 
					                if (success) this.subscribed = !this.subscribed;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,24 +127,8 @@ export default {
 | 
				
			||||||
    methods: {
 | 
					    methods: {
 | 
				
			||||||
        async fetchSubscribedStatus() {
 | 
					        async fetchSubscribedStatus() {
 | 
				
			||||||
            if (!this.channel.id) return;
 | 
					            if (!this.channel.id) return;
 | 
				
			||||||
            if (!this.authenticated) {
 | 
					 | 
				
			||||||
                this.subscribed = this.isSubscribedLocally(this.channel.id);
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.fetchJson(
 | 
					            this.subscribed = await this.fetchSubscriptionStatus(this.channel.id);
 | 
				
			||||||
                this.authApiUrl() + "/subscribed",
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    channelId: this.channel.id,
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    headers: {
 | 
					 | 
				
			||||||
                        Authorization: this.getAuthToken(),
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            ).then(json => {
 | 
					 | 
				
			||||||
                this.subscribed = json.subscribed;
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        async fetchChannel() {
 | 
					        async fetchChannel() {
 | 
				
			||||||
            const url = this.$route.path.includes("@")
 | 
					            const url = this.$route.path.includes("@")
 | 
				
			||||||
| 
						 | 
					@ -216,21 +200,9 @@ export default {
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        subscribeHandler() {
 | 
					        subscribeHandler() {
 | 
				
			||||||
            if (this.authenticated) {
 | 
					            this.toggleSubscriptionState(this.channel.id, this.subscribed).then(success => {
 | 
				
			||||||
                this.fetchJson(this.authApiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, {
 | 
					                if (success) this.subscribed = !this.subscribed;
 | 
				
			||||||
                    method: "POST",
 | 
					            });
 | 
				
			||||||
                    body: JSON.stringify({
 | 
					 | 
				
			||||||
                        channelId: this.channel.id,
 | 
					 | 
				
			||||||
                    }),
 | 
					 | 
				
			||||||
                    headers: {
 | 
					 | 
				
			||||||
                        Authorization: this.getAuthToken(),
 | 
					 | 
				
			||||||
                        "Content-Type": "application/json",
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                if (!this.handleLocalSubscriptions(this.channel.id)) return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            this.subscribed = !this.subscribed;
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        getTranslatedTabName(tabName) {
 | 
					        getTranslatedTabName(tabName) {
 | 
				
			||||||
            let translatedTabName = tabName;
 | 
					            let translatedTabName = tabName;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -551,24 +551,8 @@ export default {
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        async fetchSubscribedStatus() {
 | 
					        async fetchSubscribedStatus() {
 | 
				
			||||||
            if (!this.channelId) return;
 | 
					            if (!this.channelId) return;
 | 
				
			||||||
            if (!this.authenticated) {
 | 
					 | 
				
			||||||
                this.subscribed = this.isSubscribedLocally(this.channelId);
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.fetchJson(
 | 
					            this.subscribed = await this.fetchSubscriptionStatus(this.channelId);
 | 
				
			||||||
                this.authApiUrl() + "/subscribed",
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    channelId: this.channelId,
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    headers: {
 | 
					 | 
				
			||||||
                        Authorization: this.getAuthToken(),
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            ).then(json => {
 | 
					 | 
				
			||||||
                this.subscribed = json.subscribed;
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        rewriteComments(data) {
 | 
					        rewriteComments(data) {
 | 
				
			||||||
            data.forEach(comment => {
 | 
					            data.forEach(comment => {
 | 
				
			||||||
| 
						 | 
					@ -588,21 +572,9 @@ export default {
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        subscribeHandler() {
 | 
					        subscribeHandler() {
 | 
				
			||||||
            if (this.authenticated) {
 | 
					            this.toggleSubscriptionState(this.channelId, this.subscribed).then(success => {
 | 
				
			||||||
                this.fetchJson(this.authApiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, {
 | 
					                if (success) this.subscribed = !this.subscribed;
 | 
				
			||||||
                    method: "POST",
 | 
					            });
 | 
				
			||||||
                    body: JSON.stringify({
 | 
					 | 
				
			||||||
                        channelId: this.channelId,
 | 
					 | 
				
			||||||
                    }),
 | 
					 | 
				
			||||||
                    headers: {
 | 
					 | 
				
			||||||
                        Authorization: this.getAuthToken(),
 | 
					 | 
				
			||||||
                        "Content-Type": "application/json",
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                if (!this.handleLocalSubscriptions(this.channelId)) return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            this.subscribed = !this.subscribed;
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        handleClick(event) {
 | 
					        handleClick(event) {
 | 
				
			||||||
            if (!event || !event.target) return;
 | 
					            if (!event || !event.target) return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								src/main.js
									
										
									
									
									
								
							
							
						
						
									
										35
									
								
								src/main.js
									
										
									
									
									
								
							| 
						 | 
					@ -550,6 +550,41 @@ const mixin = {
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        async fetchSubscriptionStatus(channelId) {
 | 
				
			||||||
 | 
					            if (!this.authenticated) {
 | 
				
			||||||
 | 
					                return this.isSubscribedLocally(channelId);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const response = await this.fetchJson(
 | 
				
			||||||
 | 
					                this.authApiUrl() + "/subscribed",
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    channelId: channelId,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    headers: {
 | 
				
			||||||
 | 
					                        Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return response?.subscribed;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        async toggleSubscriptionState(channelId, subscribed) {
 | 
				
			||||||
 | 
					            if (!this.authenticated) return this.handleLocalSubscriptions(channelId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const resp = await this.fetchJson(this.authApiUrl() + (subscribed ? "/unsubscribe" : "/subscribe"), null, {
 | 
				
			||||||
 | 
					                method: "POST",
 | 
				
			||||||
 | 
					                body: JSON.stringify({
 | 
				
			||||||
 | 
					                    channelId: channelId,
 | 
				
			||||||
 | 
					                }),
 | 
				
			||||||
 | 
					                headers: {
 | 
				
			||||||
 | 
					                    Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                    "Content-Type": "application/json",
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return !resp.error;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    computed: {
 | 
					    computed: {
 | 
				
			||||||
        authenticated(_this) {
 | 
					        authenticated(_this) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue