styling, video title, disable autoplay

master
Tomáš Mládek 2020-01-10 16:11:49 +01:00
parent c54698a4aa
commit 607b845abc
2 changed files with 100 additions and 14 deletions

View File

@ -35,8 +35,20 @@ export default class App extends Vue {
</script>
<style>
html, body {
padding: 0;
margin: 0;
}
#app {
display: flex;
flex-direction: column;
align-items: center;
}
.channels {
display: flex;
padding: 2rem;
}
.channel {

View File

@ -1,8 +1,11 @@
<template>
<div :class="['channel', `channel-${state}`]">
<!--suppress HtmlFormInputWithoutLabel -->
<input class="volume" :disabled="state === 'unloaded'"
type="range" min="0" max="100" v-model="volume"/>
<div class="volume-wrapper">
<!--suppress HtmlFormInputWithoutLabel -->
<input class="volume" :disabled="state === 'unloaded'"
type="range" min="0" max="100" v-model="volume"/>
</div>
<div class="title">{{state === "loading" ? "Loading..." : title}}</div>
<div class="youtube-player" ref="ytpl"/>
</div>
</template>
@ -34,6 +37,7 @@ export default class Channel extends Vue {
private animateVolumeStart?: Date;
private animateVolumeInterval?: number;
private state = ChannelState.UNLOADED;
private title = "";
private volume: number = 50;
@ -45,6 +49,15 @@ export default class Channel extends Vue {
}
}
private get ytVideoId() {
if (this.url) {
const match = this.url.match(/v=([\w_\-]+)/);
if (match !== null && match.length == 2) {
return match[1];
}
}
}
public start() {
if (this.youtubePlayer) {
this.youtubePlayer.setVolume(this.volume);
@ -58,21 +71,33 @@ export default class Channel extends Vue {
private onUrlChange() {
if (this.url !== undefined) {
if (this.youtubePlayer === undefined) {
this.youtubePlayer = YouTubePlayerFactory(this.$refs.ytpl as HTMLDivElement);
this.youtubePlayer = YouTubePlayerFactory(this.$refs.ytpl as HTMLDivElement, {
playerVars: {"autoplay": 0},
});
this.youtubePlayer.on("stateChange", (event) => {
if (event.data == PlayerStates.BUFFERING) {
this.state = ChannelState.READY;
}
});
}
const videoId = this.url.match(/v=([\w_\-]+)/);
if (videoId !== null && videoId.length == 2) {
const videoIdMatch = this.url.match(/v=([\w_\-]+)/);
if (videoIdMatch !== null && videoIdMatch.length == 2) {
const videoId = videoIdMatch[1];
this.state = ChannelState.LOADING;
console.log(`Loading YouTube video "${videoId[1]}"`);
this.youtubePlayer.loadVideoById(videoId[1]);
console.log(`Loading YouTube video "${videoId}"`);
this.youtubePlayer.loadVideoById(videoId);
this.title = "Loading...";
Channel.fetchYoutubeTitle(videoId).then((title) => {
this.title = title;
}).catch((error) => {
console.error(error);
this.title = "ERR";
});
} else {
console.error(`Something went wrong trying to parse ${this.url}`);
}
} else {
this.title = "N/A";
}
}
@ -98,15 +123,46 @@ export default class Channel extends Vue {
}
}, 1000 / 60);
}
private static fetchYoutubeTitle(videoId: string): Promise<string> {
return new Promise((resolve, reject) => {
let url = `https://www.googleapis.com/youtube/v3/videos?part=snippet&id=${videoId}`;
if (process.env.VUE_APP_GOOGLE_API_KEY) {
url += `&key=${process.env.VUE_APP_GOOGLE_API_KEY}`;
} else {
console.warn("Using unauthenticated Google API...");
}
fetch(url).then((resp) => {
resp.json().then((jsonResp) => {
if (jsonResp["error"]) {
reject(jsonResp["error"]);
} else {
console.debug(jsonResp);
resolve(jsonResp.items[0].snippet.title);
}
}).catch((error) => {
reject(error);
});
}).catch((error) => {
reject(error);
});
});
}
}
</script>
<!--suppress CssUnusedSymbol -->
<style scoped>
.channel {
width: 128px;
height: 256px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
font-family: monospace;
font-size: 8px;
border: 1px solid black;
width: 20px;
height: 170px;
}
.channel-loading {
@ -117,14 +173,32 @@ export default class Channel extends Vue {
background: lightgray;
}
.volume-wrapper {
--height: 200px;
--width: 30px;
height: var(--height);
width: var(--width);
display: block;
}
.volume {
position: relative;
width: 150px;
height: 15px;
top: calc(150px / 2);
left: calc(150px / 2 * -1 + 15px / 2);
width: var(--height);
height: var(--width);
top: calc(var(--height) / 2);
left: calc(var(--height) / 2 * -1 + var(--width) / 2);
transform: rotate(270deg);
}
.title {
margin: .25em 1em;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-align: left;
}
</style>
<style>