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>
 | 
			
		||||
    <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">
 | 
			
		||||
                <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>
 | 
			
		||||
            <p>
 | 
			
		||||
                <span v-text="props.item.name" />
 | 
			
		||||
                <font-awesome-icon v-if="props.item.verified" class="ml-1.5" icon="check" />
 | 
			
		||||
                <span v-text="item.name" />
 | 
			
		||||
                <font-awesome-icon v-if="item.verified" class="ml-1.5" icon="check" />
 | 
			
		||||
            </p>
 | 
			
		||||
        </router-link>
 | 
			
		||||
        <p v-if="props.item.description" v-text="props.item.description" />
 | 
			
		||||
        <router-link v-if="props.item.uploaderUrl" class="link" :to="props.item.uploaderUrl">
 | 
			
		||||
        <p v-if="item.description" v-text="item.description" />
 | 
			
		||||
        <router-link v-if="item.uploaderUrl" class="link" :to="item.uploaderUrl">
 | 
			
		||||
            <p>
 | 
			
		||||
                <span v-text="props.item.uploader" />
 | 
			
		||||
                <font-awesome-icon v-if="props.item.uploaderVerified" class="ml-1.5" icon="check" />
 | 
			
		||||
                <span v-text="item.uploader" />
 | 
			
		||||
                <font-awesome-icon v-if="item.uploaderVerified" class="ml-1.5" icon="check" />
 | 
			
		||||
            </p>
 | 
			
		||||
        </router-link>
 | 
			
		||||
 | 
			
		||||
        <a v-if="props.item.uploaderName" class="link" v-text="props.item.uploaderName" />
 | 
			
		||||
        <template v-if="props.item.videos >= 0">
 | 
			
		||||
            <br v-if="props.item.uploaderName" />
 | 
			
		||||
            <strong v-text="`${props.item.videos} ${$t('video.videos')}`" />
 | 
			
		||||
        <a v-if="item.uploaderName" class="link" v-text="item.uploaderName" />
 | 
			
		||||
        <template v-if="item.videos >= 0">
 | 
			
		||||
            <br v-if="item.uploaderName" />
 | 
			
		||||
            <strong v-text="`${item.videos} ${$t('video.videos')}`" />
 | 
			
		||||
        </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 />
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    item: {
 | 
			
		||||
        type: Object,
 | 
			
		||||
        required: true,
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
    props: {
 | 
			
		||||
        item: {
 | 
			
		||||
            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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -127,24 +127,8 @@ export default {
 | 
			
		|||
    methods: {
 | 
			
		||||
        async fetchSubscribedStatus() {
 | 
			
		||||
            if (!this.channel.id) return;
 | 
			
		||||
            if (!this.authenticated) {
 | 
			
		||||
                this.subscribed = this.isSubscribedLocally(this.channel.id);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.fetchJson(
 | 
			
		||||
                this.authApiUrl() + "/subscribed",
 | 
			
		||||
                {
 | 
			
		||||
                    channelId: this.channel.id,
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    headers: {
 | 
			
		||||
                        Authorization: this.getAuthToken(),
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            ).then(json => {
 | 
			
		||||
                this.subscribed = json.subscribed;
 | 
			
		||||
            });
 | 
			
		||||
            this.subscribed = await this.fetchSubscriptionStatus(this.channel.id);
 | 
			
		||||
        },
 | 
			
		||||
        async fetchChannel() {
 | 
			
		||||
            const url = this.$route.path.includes("@")
 | 
			
		||||
| 
						 | 
				
			
			@ -216,21 +200,9 @@ export default {
 | 
			
		|||
            });
 | 
			
		||||
        },
 | 
			
		||||
        subscribeHandler() {
 | 
			
		||||
            if (this.authenticated) {
 | 
			
		||||
                this.fetchJson(this.authApiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, {
 | 
			
		||||
                    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;
 | 
			
		||||
            this.toggleSubscriptionState(this.channel.id, this.subscribed).then(success => {
 | 
			
		||||
                if (success) this.subscribed = !this.subscribed;
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        getTranslatedTabName(tabName) {
 | 
			
		||||
            let translatedTabName = tabName;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -551,24 +551,8 @@ export default {
 | 
			
		|||
        },
 | 
			
		||||
        async fetchSubscribedStatus() {
 | 
			
		||||
            if (!this.channelId) return;
 | 
			
		||||
            if (!this.authenticated) {
 | 
			
		||||
                this.subscribed = this.isSubscribedLocally(this.channelId);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.fetchJson(
 | 
			
		||||
                this.authApiUrl() + "/subscribed",
 | 
			
		||||
                {
 | 
			
		||||
                    channelId: this.channelId,
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    headers: {
 | 
			
		||||
                        Authorization: this.getAuthToken(),
 | 
			
		||||
                    },
 | 
			
		||||
                },
 | 
			
		||||
            ).then(json => {
 | 
			
		||||
                this.subscribed = json.subscribed;
 | 
			
		||||
            });
 | 
			
		||||
            this.subscribed = await this.fetchSubscriptionStatus(this.channelId);
 | 
			
		||||
        },
 | 
			
		||||
        rewriteComments(data) {
 | 
			
		||||
            data.forEach(comment => {
 | 
			
		||||
| 
						 | 
				
			
			@ -588,21 +572,9 @@ export default {
 | 
			
		|||
            });
 | 
			
		||||
        },
 | 
			
		||||
        subscribeHandler() {
 | 
			
		||||
            if (this.authenticated) {
 | 
			
		||||
                this.fetchJson(this.authApiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, {
 | 
			
		||||
                    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;
 | 
			
		||||
            this.toggleSubscriptionState(this.channelId, this.subscribed).then(success => {
 | 
			
		||||
                if (success) this.subscribed = !this.subscribed;
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        handleClick(event) {
 | 
			
		||||
            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: {
 | 
			
		||||
        authenticated(_this) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue