mirror of
				https://github.com/TeamPiped/Piped.git
				synced 2024-08-14 23:57:27 +00:00 
			
		
		
		
	
						commit
						d379d6eb0a
					
				
					 6 changed files with 173 additions and 56 deletions
				
			
		
							
								
								
									
										42
									
								
								src/components/ModalComponent.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/components/ModalComponent.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
<template>
 | 
			
		||||
    <div class="modal">
 | 
			
		||||
        <div>
 | 
			
		||||
            <div class="modal-container">
 | 
			
		||||
                <slot></slot>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
    mounted() {
 | 
			
		||||
        window.addEventListener("keydown", this.handleKeyDown);
 | 
			
		||||
    },
 | 
			
		||||
    unmounted() {
 | 
			
		||||
        window.removeEventListener("keydown", this.handleKeyDown);
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
        handleKeyDown(event) {
 | 
			
		||||
            if (event.code === "Escape") {
 | 
			
		||||
                this.$emit("close");
 | 
			
		||||
            } else return;
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<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 rounded-xl min-w-[20vw];
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,46 +1,30 @@
 | 
			
		|||
<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>
 | 
			
		||||
    <ModalComponent>
 | 
			
		||||
        <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>
 | 
			
		||||
    </div>
 | 
			
		||||
        <select class="select w-full mt-3" v-model="selectedPlaylist">
 | 
			
		||||
            <option v-for="playlist in playlists" :value="playlist.id" :key="playlist.id" v-text="playlist.name" />
 | 
			
		||||
        </select>
 | 
			
		||||
        <div class="flex justify-end mt-3">
 | 
			
		||||
            <button
 | 
			
		||||
                class="btn"
 | 
			
		||||
                @click="handleClick(selectedPlaylist)"
 | 
			
		||||
                ref="addButton"
 | 
			
		||||
                v-t="'actions.add_to_playlist'"
 | 
			
		||||
            />
 | 
			
		||||
        </div>
 | 
			
		||||
    </ModalComponent>
 | 
			
		||||
</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>
 | 
			
		||||
import ModalComponent from "./ModalComponent.vue";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    components: {
 | 
			
		||||
        ModalComponent,
 | 
			
		||||
    },
 | 
			
		||||
    props: {
 | 
			
		||||
        videoId: {
 | 
			
		||||
            type: String,
 | 
			
		||||
| 
						 | 
				
			
			@ -65,12 +49,10 @@ export default {
 | 
			
		|||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
        handleKeyDown(event) {
 | 
			
		||||
            if (event.code === "Escape") {
 | 
			
		||||
                this.$emit("close");
 | 
			
		||||
            } else if (event.code === "Enter") {
 | 
			
		||||
            if (event.code === "Enter") {
 | 
			
		||||
                this.handleClick(this.selectedPlaylist);
 | 
			
		||||
            } else return;
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
                event.preventDefault();
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        handleClick(playlistId) {
 | 
			
		||||
            if (!playlistId) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										80
									
								
								src/components/ShareModal.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/components/ShareModal.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,80 @@
 | 
			
		|||
<template>
 | 
			
		||||
    <ModalComponent>
 | 
			
		||||
        <div class="flex">
 | 
			
		||||
            <h2 v-t="'actions.share'" />
 | 
			
		||||
            <button class="ml-3" @click="$emit('close')"><font-awesome-icon icon="xmark" /></button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="flex justify-between mt-4">
 | 
			
		||||
            <label v-t="'actions.with_timecode'" for="withTimeCode" />
 | 
			
		||||
            <input id="withTimeCode" type="checkbox" v-model="withTimeCode" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="flex justify-between">
 | 
			
		||||
            <label v-t="'actions.piped_link'" />
 | 
			
		||||
            <input type="checkbox" v-model="pipedLink" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="flex justify-between mt-2">
 | 
			
		||||
            <label v-t="'actions.time_code'" />
 | 
			
		||||
            <input class="input w-12" type="text" v-model="timeStamp" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <h3 class="mt-4" v-text="generatedLink" />
 | 
			
		||||
        <div class="flex justify-end mt-4">
 | 
			
		||||
            <button class="btn" v-t="'actions.follow_link'" @click="followLink()" />
 | 
			
		||||
            <button class="btn ml-3" v-t="'actions.copy_link'" @click="copyLink()" />
 | 
			
		||||
        </div>
 | 
			
		||||
    </ModalComponent>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import ModalComponent from "./ModalComponent.vue";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    props: {
 | 
			
		||||
        videoId: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            required: true,
 | 
			
		||||
        },
 | 
			
		||||
        currentTime: {
 | 
			
		||||
            type: Number,
 | 
			
		||||
            required: true,
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    components: {
 | 
			
		||||
        ModalComponent,
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            withTimeCode: true,
 | 
			
		||||
            pipedLink: true,
 | 
			
		||||
            timeStamp: null,
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    mounted() {
 | 
			
		||||
        this.timeStamp = parseInt(this.currentTime);
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
        followLink() {
 | 
			
		||||
            window.open(this.generatedLink, "_blank").focus();
 | 
			
		||||
        },
 | 
			
		||||
        async copyLink() {
 | 
			
		||||
            await this.copyURL(this.generatedLink);
 | 
			
		||||
        },
 | 
			
		||||
        async copyURL(mytext) {
 | 
			
		||||
            try {
 | 
			
		||||
                await navigator.clipboard.writeText(mytext);
 | 
			
		||||
                alert(this.$t("info.copied"));
 | 
			
		||||
            } catch ($e) {
 | 
			
		||||
                alert(this.$t("info.cannot_copy"));
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    computed: {
 | 
			
		||||
        generatedLink() {
 | 
			
		||||
            var href = this.pipedLink
 | 
			
		||||
                ? window.location.origin + "/watch?v=" + this.videoId
 | 
			
		||||
                : "https://youtu.be/" + this.videoId;
 | 
			
		||||
            if (this.withTimeCode && this.timeStamp > 0) href += "?t=" + this.timeStamp;
 | 
			
		||||
            return href;
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +88,12 @@
 | 
			
		|||
                    />
 | 
			
		||||
                </div>
 | 
			
		||||
                <PlaylistAddModal v-if="showModal" :video-id="getVideoId()" @close="showModal = !showModal" />
 | 
			
		||||
                <ShareModal
 | 
			
		||||
                    v-if="showShareModal"
 | 
			
		||||
                    :video-id="getVideoId()"
 | 
			
		||||
                    :current-time="currentTime"
 | 
			
		||||
                    @close="showShareModal = !showShareModal"
 | 
			
		||||
                />
 | 
			
		||||
                <div class="flex">
 | 
			
		||||
                    <div class="self-center children:mr-1 my-1">
 | 
			
		||||
                        <!-- RSS Feed button -->
 | 
			
		||||
| 
						 | 
				
			
			@ -105,15 +111,10 @@
 | 
			
		|||
                            <font-awesome-icon icon="rss" />
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <!-- watch on youtube button -->
 | 
			
		||||
                        <a :href="`https://youtu.be/${getVideoId()}`" class="btn lt-lg:hidden">
 | 
			
		||||
                            <i18n-t keypath="player.watch_on" tag="strong">
 | 
			
		||||
                                <font-awesome-icon class="mx-1.5" :icon="['fab', 'youtube']" />
 | 
			
		||||
                            </i18n-t>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <!-- only visible on small screens -->
 | 
			
		||||
                        <a :href="`https://youtu.be/${getVideoId()}`" class="btn lg:hidden">
 | 
			
		||||
                            <font-awesome-icon class="mx-1.5" :icon="['fab', 'youtube']" />
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <button class="btn" @click="showShareModal = !showShareModal">
 | 
			
		||||
                            <i18n-t class="lt-lg:hidden" keypath="actions.share" tag="strong"></i18n-t>
 | 
			
		||||
                            <font-awesome-icon class="mx-1.5" icon="fa-share" />
 | 
			
		||||
                        </button>
 | 
			
		||||
                        <!-- LBRY -->
 | 
			
		||||
                        <a v-if="video.lbryId" :href="'https://odysee.com/' + video.lbryId" class="btn">
 | 
			
		||||
                            <i18n-t keypath="player.watch_on" tag="strong">LBRY</i18n-t>
 | 
			
		||||
| 
						 | 
				
			
			@ -211,6 +212,7 @@ import ErrorHandler from "./ErrorHandler.vue";
 | 
			
		|||
import CommentItem from "./CommentItem.vue";
 | 
			
		||||
import ChaptersBar from "./ChaptersBar.vue";
 | 
			
		||||
import PlaylistAddModal from "./PlaylistAddModal.vue";
 | 
			
		||||
import ShareModal from "./ShareModal.vue";
 | 
			
		||||
import PlaylistVideos from "./PlaylistVideos.vue";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
| 
						 | 
				
			
			@ -222,6 +224,7 @@ export default {
 | 
			
		|||
        CommentItem,
 | 
			
		||||
        ChaptersBar,
 | 
			
		||||
        PlaylistAddModal,
 | 
			
		||||
        ShareModal,
 | 
			
		||||
        PlaylistVideos,
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
| 
						 | 
				
			
			@ -245,6 +248,7 @@ export default {
 | 
			
		|||
            smallViewQuery: smallViewQuery,
 | 
			
		||||
            smallView: smallViewQuery.matches,
 | 
			
		||||
            showModal: false,
 | 
			
		||||
            showShareModal: false,
 | 
			
		||||
            isMobile: true,
 | 
			
		||||
            currentTime: 0,
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,7 +97,13 @@
 | 
			
		|||
        "confirm_reset_preferences": "Are you sure you want to reset your preferences?",
 | 
			
		||||
        "backup_preferences": "Backup preferences",
 | 
			
		||||
        "restore_preferences": "Restore preferences",
 | 
			
		||||
        "back_to_home": "Back to home"
 | 
			
		||||
        "back_to_home": "Back to home",
 | 
			
		||||
        "share": "Share",
 | 
			
		||||
        "with_timecode": "Share with time code",
 | 
			
		||||
        "piped_link": "Piped link",
 | 
			
		||||
        "follow_link": "Follow link",
 | 
			
		||||
        "copy_link": "Copy link",
 | 
			
		||||
        "time_code": "Time code (in seconds)"
 | 
			
		||||
    },
 | 
			
		||||
    "comment": {
 | 
			
		||||
        "pinned_by": "Pinned by",
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +150,8 @@
 | 
			
		|||
    },
 | 
			
		||||
    "info": {
 | 
			
		||||
        "preferences_note": "Note: preferences are saved in the local storage of your browser. Deleting your browser data will reset them.",
 | 
			
		||||
        "page_not_found": "Page not found"
 | 
			
		||||
        "page_not_found": "Page not found",
 | 
			
		||||
        "copied": "Copied!",
 | 
			
		||||
        "cannot_copy": "Can't copy!"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,8 +16,9 @@ import {
 | 
			
		|||
    faCircleMinus,
 | 
			
		||||
    faXmark,
 | 
			
		||||
    faClone,
 | 
			
		||||
    faShare,
 | 
			
		||||
} from "@fortawesome/free-solid-svg-icons";
 | 
			
		||||
import { faGithub, faBitcoin, faYoutube } from "@fortawesome/free-brands-svg-icons";
 | 
			
		||||
import { faGithub, faBitcoin } from "@fortawesome/free-brands-svg-icons";
 | 
			
		||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
 | 
			
		||||
library.add(
 | 
			
		||||
    faEye,
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +28,6 @@ library.add(
 | 
			
		|||
    faCheck,
 | 
			
		||||
    faHeart,
 | 
			
		||||
    faHeadphones,
 | 
			
		||||
    faYoutube,
 | 
			
		||||
    faRss,
 | 
			
		||||
    faChevronLeft,
 | 
			
		||||
    faLevelDownAlt,
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ library.add(
 | 
			
		|||
    faCircleMinus,
 | 
			
		||||
    faXmark,
 | 
			
		||||
    faClone,
 | 
			
		||||
    faShare,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
import router from "@/router/router.js";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue