mirror of
				https://github.com/TeamPiped/Piped.git
				synced 2024-08-14 23:57:27 +00:00 
			
		
		
		
	Add support for playlists.
This commit is contained in:
		
							parent
							
								
									ca3206b21a
								
							
						
					
					
						commit
						4d18bf8004
					
				
					 8 changed files with 266 additions and 4 deletions
				
			
		| 
						 | 
					@ -39,6 +39,9 @@
 | 
				
			||||||
                <li v-if="shouldShowHistory">
 | 
					                <li v-if="shouldShowHistory">
 | 
				
			||||||
                    <router-link v-t="'titles.history'" to="/history" />
 | 
					                    <router-link v-t="'titles.history'" to="/history" />
 | 
				
			||||||
                </li>
 | 
					                </li>
 | 
				
			||||||
 | 
					                <li v-if="authenticated">
 | 
				
			||||||
 | 
					                    <router-link v-t="'titles.playlists'" to="/playlists" />
 | 
				
			||||||
 | 
					                </li>
 | 
				
			||||||
                <li v-if="authenticated">
 | 
					                <li v-if="authenticated">
 | 
				
			||||||
                    <router-link v-t="'titles.feed'" to="/feed" />
 | 
					                    <router-link v-t="'titles.feed'" to="/feed" />
 | 
				
			||||||
                </li>
 | 
					                </li>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										94
									
								
								src/components/PlaylistAddModal.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/components/PlaylistAddModal.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,94 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div class="modal">
 | 
				
			||||||
 | 
					        <div>
 | 
				
			||||||
 | 
					            <div class="modal-container">
 | 
				
			||||||
 | 
					                <div class="flex">
 | 
				
			||||||
 | 
					                    <span class="text-2xl w-max inline-block" v-t="'actions.select_playlist'" />
 | 
				
			||||||
 | 
					                    <button class="ml-3" @click="$emit('close')"><font-awesome-icon icon="xmark" /></button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <select class="select w-full" v-model="selectedPlaylist">
 | 
				
			||||||
 | 
					                    <option
 | 
				
			||||||
 | 
					                        v-for="playlist in playlists"
 | 
				
			||||||
 | 
					                        :value="playlist.id"
 | 
				
			||||||
 | 
					                        :key="playlist.id"
 | 
				
			||||||
 | 
					                        v-text="playlist.name"
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                </select>
 | 
				
			||||||
 | 
					                <button
 | 
				
			||||||
 | 
					                    class="btn mt-2"
 | 
				
			||||||
 | 
					                    @click="handleClick(selectedPlaylist)"
 | 
				
			||||||
 | 
					                    ref="addButton"
 | 
				
			||||||
 | 
					                    v-t="'actions.add_to_playlist'"
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					.modal {
 | 
				
			||||||
 | 
					    @apply fixed z-50 top-0 left-0 w-full h-full bg-dark-900 bg-opacity-80 transition-opacity table;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.modal > div {
 | 
				
			||||||
 | 
					    @apply table-cell align-middle;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.modal-container {
 | 
				
			||||||
 | 
					    @apply w-min m-auto px-8 bg-dark-700 p-6;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    props: {
 | 
				
			||||||
 | 
					        videoId: {
 | 
				
			||||||
 | 
					            type: String,
 | 
				
			||||||
 | 
					            required: true,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    data() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            playlists: [],
 | 
				
			||||||
 | 
					            selectedPlaylist: null,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    mounted() {
 | 
				
			||||||
 | 
					        this.fetchPlaylists();
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					        handleClick(playlistId) {
 | 
				
			||||||
 | 
					            if (!playlistId) {
 | 
				
			||||||
 | 
					                alert(this.$t("actions.please_select_playlist"));
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.$refs.addButton.disabled = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.fetchJson(this.apiUrl() + "/user/playlists/add", null, {
 | 
				
			||||||
 | 
					                method: "POST",
 | 
				
			||||||
 | 
					                body: JSON.stringify({
 | 
				
			||||||
 | 
					                    playlistId: playlistId,
 | 
				
			||||||
 | 
					                    videoId: this.videoId,
 | 
				
			||||||
 | 
					                }),
 | 
				
			||||||
 | 
					                headers: {
 | 
				
			||||||
 | 
					                    Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                    "Content-Type": "application/json",
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }).then(json => {
 | 
				
			||||||
 | 
					                this.$emit("close");
 | 
				
			||||||
 | 
					                if (json.error) alert(json.error);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        async fetchPlaylists() {
 | 
				
			||||||
 | 
					            this.fetchJson(this.apiUrl() + "/user/playlists", null, {
 | 
				
			||||||
 | 
					                headers: {
 | 
				
			||||||
 | 
					                    Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }).then(json => {
 | 
				
			||||||
 | 
					                this.playlists = json;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -26,9 +26,13 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="video-grid">
 | 
					        <div class="video-grid">
 | 
				
			||||||
            <VideoItem
 | 
					            <VideoItem
 | 
				
			||||||
                v-for="video in playlist.relatedStreams"
 | 
					                v-for="(video, index) in playlist.relatedStreams"
 | 
				
			||||||
                :key="video.url"
 | 
					                :key="video.url"
 | 
				
			||||||
                :video="video"
 | 
					                :video="video"
 | 
				
			||||||
 | 
					                :index="index"
 | 
				
			||||||
 | 
					                :playlist-id="$route.query.list"
 | 
				
			||||||
 | 
					                :admin="admin"
 | 
				
			||||||
 | 
					                @remove="removeVideo(index)"
 | 
				
			||||||
                height="94"
 | 
					                height="94"
 | 
				
			||||||
                width="168"
 | 
					                width="168"
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
| 
						 | 
					@ -48,6 +52,7 @@ export default {
 | 
				
			||||||
    data() {
 | 
					    data() {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            playlist: null,
 | 
					            playlist: null,
 | 
				
			||||||
 | 
					            admin: false,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    computed: {
 | 
					    computed: {
 | 
				
			||||||
| 
						 | 
					@ -57,6 +62,16 @@ export default {
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    mounted() {
 | 
					    mounted() {
 | 
				
			||||||
        this.getPlaylistData();
 | 
					        this.getPlaylistData();
 | 
				
			||||||
 | 
					        const playlistId = this.$route.query.list;
 | 
				
			||||||
 | 
					        if (this.authenticated && playlistId?.length == 36)
 | 
				
			||||||
 | 
					            this.fetchJson(this.apiUrl() + "/user/playlists", null, {
 | 
				
			||||||
 | 
					                headers: {
 | 
				
			||||||
 | 
					                    Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }).then(json => {
 | 
				
			||||||
 | 
					                if (json.error) alert(json.error);
 | 
				
			||||||
 | 
					                else if (json.filter(playlist => playlist.id === playlistId).length > 0) this.admin = true;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    activated() {
 | 
					    activated() {
 | 
				
			||||||
        window.addEventListener("scroll", this.handleScroll);
 | 
					        window.addEventListener("scroll", this.handleScroll);
 | 
				
			||||||
| 
						 | 
					@ -87,6 +102,9 @@ export default {
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        removeVideo(index) {
 | 
				
			||||||
 | 
					            this.playlist.relatedStreams.splice(index, 1);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										83
									
								
								src/components/PlaylistsPage.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/components/PlaylistsPage.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,83 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <h1 class="font-bold text-center" v-t="'titles.playlists'" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <hr />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <button v-t="'actions.create_playlist'" class="btn" @click="createPlaylist" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="video-grid">
 | 
				
			||||||
 | 
					        <div v-for="playlist in playlists" :key="playlist.id">
 | 
				
			||||||
 | 
					            <router-link :to="`/playlist?list=${playlist.id}`">
 | 
				
			||||||
 | 
					                <img class="w-full" :src="playlist.thumbnail" alt="thumbnail" />
 | 
				
			||||||
 | 
					                <p
 | 
				
			||||||
 | 
					                    style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical"
 | 
				
			||||||
 | 
					                    class="my-2 overflow-hidden flex link"
 | 
				
			||||||
 | 
					                    :title="playlist.name"
 | 
				
			||||||
 | 
					                    v-text="playlist.name"
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					            </router-link>
 | 
				
			||||||
 | 
					            <button class="btn h-auto" @click="deletePlaylist(playlist.id)" v-t="'actions.delete_playlist'" />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <br />
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    data() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            playlists: [],
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    mounted() {
 | 
				
			||||||
 | 
					        if (this.authenticated) this.fetchPlaylists();
 | 
				
			||||||
 | 
					        else this.$router.push("/login");
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    activated() {
 | 
				
			||||||
 | 
					        document.title = this.$t("titles.playlists") + " - Piped";
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					        fetchPlaylists() {
 | 
				
			||||||
 | 
					            this.fetchJson(this.apiUrl() + "/user/playlists", null, {
 | 
				
			||||||
 | 
					                headers: {
 | 
				
			||||||
 | 
					                    Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }).then(json => {
 | 
				
			||||||
 | 
					                this.playlists = json;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        deletePlaylist(id) {
 | 
				
			||||||
 | 
					            if (confirm(this.$t("actions.delete_playlist_confirm")))
 | 
				
			||||||
 | 
					                this.fetchJson(this.apiUrl() + "/user/playlists/delete", null, {
 | 
				
			||||||
 | 
					                    method: "POST",
 | 
				
			||||||
 | 
					                    body: JSON.stringify({
 | 
				
			||||||
 | 
					                        playlistId: id,
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                    headers: {
 | 
				
			||||||
 | 
					                        Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                        "Content-Type": "application/json",
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                }).then(json => {
 | 
				
			||||||
 | 
					                    if (json.error) alert(json.error);
 | 
				
			||||||
 | 
					                    else this.playlists = this.playlists.filter(playlist => playlist.id !== id);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        createPlaylist() {
 | 
				
			||||||
 | 
					            const name = prompt(this.$t("actions.create_playlist"));
 | 
				
			||||||
 | 
					            this.fetchJson(this.apiUrl() + "/user/playlists/create", null, {
 | 
				
			||||||
 | 
					                method: "POST",
 | 
				
			||||||
 | 
					                body: JSON.stringify({
 | 
				
			||||||
 | 
					                    name: name,
 | 
				
			||||||
 | 
					                }),
 | 
				
			||||||
 | 
					                headers: {
 | 
				
			||||||
 | 
					                    Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                    "Content-Type": "application/json",
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            }).then(json => {
 | 
				
			||||||
 | 
					                if (json.error) alert(json.error);
 | 
				
			||||||
 | 
					                else this.fetchPlaylists();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </router-link>
 | 
					        </router-link>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="float-right m-0 inline-block">
 | 
					        <div class="float-right m-0 inline-block children:px-1">
 | 
				
			||||||
            <router-link
 | 
					            <router-link
 | 
				
			||||||
                :to="video.url + '&listen=1'"
 | 
					                :to="video.url + '&listen=1'"
 | 
				
			||||||
                :aria-label="'Listen to ' + video.title"
 | 
					                :aria-label="'Listen to ' + video.title"
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,18 @@
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
                <font-awesome-icon icon="headphones" />
 | 
					                <font-awesome-icon icon="headphones" />
 | 
				
			||||||
            </router-link>
 | 
					            </router-link>
 | 
				
			||||||
 | 
					            <button v-if="authenticated" :title="$t('actions.add_to_playlist')" @click="showModal = !showModal">
 | 
				
			||||||
 | 
					                <font-awesome-icon icon="circle-plus" />
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					            <button
 | 
				
			||||||
 | 
					                v-if="admin"
 | 
				
			||||||
 | 
					                :title="$t('actions.remove_from_playlist')"
 | 
				
			||||||
 | 
					                ref="removeButton"
 | 
				
			||||||
 | 
					                @click="removeVideo(video.url.substr(-11))"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                <font-awesome-icon icon="circle-minus" />
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					            <PlaylistAddModal v-if="showModal" :video-id="video.url.substr(-11)" @close="showModal = !showModal" />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="flex">
 | 
					        <div class="flex">
 | 
				
			||||||
| 
						 | 
					@ -82,6 +94,8 @@
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
 | 
					import PlaylistAddModal from "./PlaylistAddModal.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
    props: {
 | 
					    props: {
 | 
				
			||||||
        video: {
 | 
					        video: {
 | 
				
			||||||
| 
						 | 
					@ -93,6 +107,36 @@ export default {
 | 
				
			||||||
        height: { type: String, default: "118" },
 | 
					        height: { type: String, default: "118" },
 | 
				
			||||||
        width: { type: String, default: "210" },
 | 
					        width: { type: String, default: "210" },
 | 
				
			||||||
        hideChannel: { type: Boolean, default: false },
 | 
					        hideChannel: { type: Boolean, default: false },
 | 
				
			||||||
 | 
					        index: { type: Number, default: -1 },
 | 
				
			||||||
 | 
					        playlistId: { type: String, default: null },
 | 
				
			||||||
 | 
					        admin: { type: Boolean, default: false },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    data() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            showModal: false,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					        removeVideo() {
 | 
				
			||||||
 | 
					            if (confirm(this.$t("actions.delete_playlist_video_confirm"))) {
 | 
				
			||||||
 | 
					                this.$refs.removeButton.disabled = true;
 | 
				
			||||||
 | 
					                this.fetchJson(this.apiUrl() + "/user/playlists/remove", null, {
 | 
				
			||||||
 | 
					                    method: "POST",
 | 
				
			||||||
 | 
					                    body: JSON.stringify({
 | 
				
			||||||
 | 
					                        playlistId: this.playlistId,
 | 
				
			||||||
 | 
					                        index: this.index,
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                    headers: {
 | 
				
			||||||
 | 
					                        Authorization: this.getAuthToken(),
 | 
				
			||||||
 | 
					                        "Content-Type": "application/json",
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                }).then(json => {
 | 
				
			||||||
 | 
					                    if (json.error) alert(json.error);
 | 
				
			||||||
 | 
					                    else this.$emit("remove");
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    components: { PlaylistAddModal },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,8 @@
 | 
				
			||||||
        "feed": "Feed",
 | 
					        "feed": "Feed",
 | 
				
			||||||
        "preferences": "Preferences",
 | 
					        "preferences": "Preferences",
 | 
				
			||||||
        "history": "History",
 | 
					        "history": "History",
 | 
				
			||||||
        "subscriptions": "Subscriptions"
 | 
					        "subscriptions": "Subscriptions",
 | 
				
			||||||
 | 
					        "playlists": "Playlists"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "player": {
 | 
					    "player": {
 | 
				
			||||||
        "watch_on": "Watch on {0}"
 | 
					        "watch_on": "Watch on {0}"
 | 
				
			||||||
| 
						 | 
					@ -70,7 +71,15 @@
 | 
				
			||||||
        "clear_history": "Clear History",
 | 
					        "clear_history": "Clear History",
 | 
				
			||||||
        "show_replies": "Show Replies",
 | 
					        "show_replies": "Show Replies",
 | 
				
			||||||
        "hide_replies": "Hide Replies",
 | 
					        "hide_replies": "Hide Replies",
 | 
				
			||||||
        "load_more_replies": "Load more Replies"
 | 
					        "load_more_replies": "Load more Replies",
 | 
				
			||||||
 | 
					        "add_to_playlist": "Add to playlist",
 | 
				
			||||||
 | 
					        "remove_from_playlist": "Remove from playlist",
 | 
				
			||||||
 | 
					        "delete_playlist_video_confirm": "Are you sure you would like to remove this video from this playlist?",
 | 
				
			||||||
 | 
					        "create_playlist": "Create Playlist",
 | 
				
			||||||
 | 
					        "delete_playlist": "Delete Playlist",
 | 
				
			||||||
 | 
					        "select_playlist": "Select a Playlist",
 | 
				
			||||||
 | 
					        "delete_playlist_confirm": "Are you sure you want to delete this playlist?",
 | 
				
			||||||
 | 
					        "please_select_playlist": "Please select a playlist"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "comment": {
 | 
					    "comment": {
 | 
				
			||||||
        "pinned_by": "Pinned by"
 | 
					        "pinned_by": "Pinned by"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,9 @@ import {
 | 
				
			||||||
    faTv,
 | 
					    faTv,
 | 
				
			||||||
    faLevelUpAlt,
 | 
					    faLevelUpAlt,
 | 
				
			||||||
    faBroadcastTower,
 | 
					    faBroadcastTower,
 | 
				
			||||||
 | 
					    faCirclePlus,
 | 
				
			||||||
 | 
					    faCircleMinus,
 | 
				
			||||||
 | 
					    faXmark,
 | 
				
			||||||
} from "@fortawesome/free-solid-svg-icons";
 | 
					} from "@fortawesome/free-solid-svg-icons";
 | 
				
			||||||
import { faGithub, faBitcoin, faYoutube } from "@fortawesome/free-brands-svg-icons";
 | 
					import { faGithub, faBitcoin, faYoutube } from "@fortawesome/free-brands-svg-icons";
 | 
				
			||||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
 | 
					import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
 | 
				
			||||||
| 
						 | 
					@ -34,6 +37,9 @@ library.add(
 | 
				
			||||||
    faLevelUpAlt,
 | 
					    faLevelUpAlt,
 | 
				
			||||||
    faTv,
 | 
					    faTv,
 | 
				
			||||||
    faBroadcastTower,
 | 
					    faBroadcastTower,
 | 
				
			||||||
 | 
					    faCirclePlus,
 | 
				
			||||||
 | 
					    faCircleMinus,
 | 
				
			||||||
 | 
					    faXmark,
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import router from "@/router/router.js";
 | 
					import router from "@/router/router.js";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,6 +70,11 @@ const routes = [
 | 
				
			||||||
        name: "Watch History",
 | 
					        name: "Watch History",
 | 
				
			||||||
        component: () => import("../components/HistoryPage.vue"),
 | 
					        component: () => import("../components/HistoryPage.vue"),
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        path: "/playlists",
 | 
				
			||||||
 | 
					        name: "Playlists",
 | 
				
			||||||
 | 
					        component: () => import("../components/PlaylistsPage.vue"),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = createRouter({
 | 
					const router = createRouter({
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue