Created
July 28, 2020 13:31
-
-
Save martinherweg/3297e02867eff18902ab0c5dcfcc5587 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable */ | |
import Vue from "vue"; | |
import VueCompositionAPI, { | |
computed, | |
onBeforeMount, | |
reactive, | |
toRefs, | |
} from "@vue/composition-api"; | |
import { useVideoPlayer } from "../../../helpers/videoPlayer/videoPlayerFunctions"; | |
Vue.use(VueCompositionAPI); | |
const state = reactive({ | |
activeVideo: {}, | |
videos: [], | |
}) | |
// eslint-disable-next-line | |
export function useVideoGallery(videos = []) { | |
state.videos = videos; | |
const { toggleVideo } = useVideoPlayer() | |
function setActiveVideo(video, { startVideo = false } = {}) { | |
state.activeVideo = video; | |
if (startVideo) { | |
Vue.nextTick(() => toggleVideo()); | |
} | |
} | |
onBeforeMount(() => { | |
setActiveVideo(state.videos[0]); | |
}); | |
const upNext = computed(() => { | |
const lastVideo = state.videos[state.videos.length - 1]; | |
if (lastVideo?.id === state.activeVideo?.id) { | |
return state.videos[0]; | |
} | |
return state.videos.find((video) => video.id === state.activeVideo?.id + 1); | |
}); | |
return { | |
...toRefs(state), | |
setActiveVideo, | |
upNext, | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="video-gallery__full"> | |
<div | |
class="video-gallery-container" | |
:class="{ | |
'video-gallery-container--playing': videoIsPlaying, | |
'video-gallery-container--stopped': !videoIsPlaying, | |
'video-gallery-container--ended': videoHasFinished, | |
}" | |
@click="toggleVideo" | |
> | |
<video-wrapper> | |
<RawIcon | |
v-show="!videoIsPlaying && !videoHasFinished" | |
:icon="icons.playButton" | |
/> | |
<template v-if="hasUpNext"> | |
<button v-show="videoHasFinished" class="video-gallery-next"> | |
<div | |
class="video-gallery-next__wrapper" | |
@click="setActiveVideo(upNext, { startVideo: true })" | |
> | |
<h4 class="video-gallery-next__title">Up next</h4> | |
<div class="video-gallery-next__thumb"> | |
<video-wrapper> | |
<img | |
width="384" | |
height="217" | |
class="lazyload" | |
:data-src="upNext.thumbnail.src" | |
:data-srcset="upNext.thumbnail.srcset" | |
alt="" | |
/> | |
</video-wrapper> | |
</div> | |
</div> | |
</button> | |
</template> | |
<video-player | |
:key="activeVideo.id" | |
ref="videoPlayer" | |
:src="activeVideo.src" | |
:video-is-playing="videoIsPlaying" | |
/> | |
</video-wrapper> | |
</div> | |
</div> | |
</template> | |
<script> | |
import { computed, ref } from "@vue/composition-api"; | |
import VideoWrapper from "../../helpers/videoWrapper/VideoWrapper.vue"; | |
import VideoPlayer from "../../helpers/videoPlayer/videoPlayer.vue"; | |
import RawIcon from "../../helpers/RawIcon.vue"; | |
import { useVideoGallery } from "./use/useVideoGallery"; | |
import { useVideoPlayer } from "../../helpers/videoPlayer/videoPlayerFunctions"; | |
export default { | |
name: "VideoGalleryFull", | |
components: { VideoPlayer, RawIcon, VideoWrapper }, | |
props: { | |
activeVideo: { | |
type: Object, | |
required: true, | |
}, | |
upNext: { | |
type: Object, | |
required: true, | |
}, | |
translations: { | |
type: Object, | |
default: () => ({ | |
upNext: "Up Next", | |
}), | |
required: true, | |
}, | |
icons: { | |
type: Object, | |
default: () => ({ playButton: "" }), | |
required: true, | |
}, | |
}, | |
setup() { | |
const videoPlayer = ref(0); | |
const { videoIsPlaying, videoHasFinished, toggleVideo } = useVideoPlayer( | |
videoPlayer | |
); | |
const { setActiveVideo, upNext } = useVideoGallery(); | |
const hasUpNext = computed(() => { | |
return upNext && Object.keys(upNext).length > 0; | |
}); | |
return { | |
toggleVideo, | |
setActiveVideo, | |
videoIsPlaying, | |
videoHasFinished, | |
hasUpNext, | |
upNext, | |
}; | |
}, | |
}; | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="video-gallery"> | |
<video-gallery-full | |
:active-video="activeVideo" | |
:up-next="upNext" | |
:icons="icons" | |
:translations="translations" | |
/> | |
<video-gallery-list | |
v-if="showGalleryList" | |
:videos="videos" | |
:active-video="activeVideo" | |
:set-active-video="setActiveVideo" | |
:icons="icons" | |
/> | |
</div> | |
</template> | |
<script> | |
/* eslint-disable */ | |
import { computed, onMounted } from "@vue/composition-api"; | |
import VideoGalleryFull from "./videoGallery--full.vue"; | |
import VideoGalleryList from "./videoGallery--list.vue"; | |
import { useVideoGallery } from "./use/useVideoGallery"; | |
export default { | |
name: "VideoGallery", | |
components: { VideoGalleryList, VideoGalleryFull }, | |
props: { | |
videos: { | |
type: Array, | |
required: true, | |
}, | |
icons: { | |
type: Object, | |
required: true, | |
}, | |
translations: { | |
type: Object, | |
required: true, | |
}, | |
}, | |
setup(props) { | |
const showGalleryList = computed(() => props.videos.length > 1); | |
onMounted(() => { | |
const { activeVideo, upNext, setActiveVideo } = useVideoGallery(props.videos); | |
}) | |
return { | |
showGalleryList, | |
activeVideo, | |
upNext, | |
setActiveVideo | |
}; | |
}, | |
}; | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vue from "vue"; | |
import VueCompositionAPI, { | |
onBeforeUnmount, | |
onMounted, | |
reactive, | |
toRefs, | |
} from "@vue/composition-api"; | |
Vue.use(VueCompositionAPI); | |
// eslint-disable-next-line | |
export function useVideoPlayer(fullVideoRef) { | |
let fullVideo = null; | |
const videoState = reactive({ | |
videoIsPlaying: false, | |
videoHasFinished: false, | |
}); | |
function setVideoIsPlaying(playState) { | |
videoState.videoIsPlaying = playState; | |
if (fullVideo && playState) { | |
fullVideo.play(); | |
} | |
} | |
function setVideoHasFinished(finishState) { | |
videoState.videoHasFinished = finishState; | |
if (finishState) { | |
setVideoIsPlaying(false); | |
} | |
} | |
function toggleVideo() { | |
setVideoIsPlaying(true); | |
setVideoHasFinished(false); | |
} | |
const handleVideoPlay = function () { | |
setVideoIsPlaying(true); | |
}; | |
const handleVideoPause = function () { | |
setVideoIsPlaying(false); | |
}; | |
const handleVideoFinished = function () { | |
setVideoHasFinished(true); | |
}; | |
onMounted(() => { | |
if (fullVideoRef) { | |
fullVideo = fullVideoRef.value.$el; | |
console.log(fullVideo); | |
} | |
fullVideo.addEventListener("playing", handleVideoPlay); | |
fullVideo.addEventListener("pause", handleVideoPause); | |
fullVideo.addEventListener("ended", handleVideoFinished); | |
}); | |
onBeforeUnmount(() => { | |
if (!fullVideo || fullVideo === null) { | |
return; | |
} | |
fullVideo.removeEventListener("playing", handleVideoPlay); | |
fullVideo.removeEventListener("pause", handleVideoPause); | |
fullVideo.removeEventListener("ended", handleVideoFinished); | |
}); | |
return { | |
...toRefs(videoState), | |
fullVideo, | |
toggleVideo, | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment