add basic url input, styling
This commit is contained in:
parent
06ffaa02df
commit
8ebeeecb03
2 changed files with 77 additions and 11 deletions
70
src/App.vue
70
src/App.vue
|
@ -1,11 +1,26 @@
|
|||
<!--suppress HtmlFormInputWithoutLabel -->
|
||||
<template>
|
||||
<div id="app">
|
||||
<div class="channels">
|
||||
<template v-for="i in N_CHANNELS">
|
||||
<Channel :url="defaultMedia[i-1]" :volume="volumes[i-1]" :key="i" class="channel" ref="channels"/>
|
||||
</template>
|
||||
<div class="channels-wrapper">
|
||||
<div class="channels">
|
||||
<template v-for="i in N_CHANNELS">
|
||||
<Channel :name="names[i - 1]" :url="urls[i - 1]" :volume="volumes[i-1]"
|
||||
:key="i"
|
||||
class="channel" ref="channels"/>
|
||||
</template>
|
||||
</div>
|
||||
<div class="channel-urls">
|
||||
<div class="url-input" v-for="i in N_CHANNELS">
|
||||
<label :for="`url-input-${names[i-1]}`">
|
||||
{{names[i - 1]}}
|
||||
</label>
|
||||
<input :id="`url-input-${names[i-1]}`" type="text" v-model="urls[i - 1]"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<button @click="start">START</button>
|
||||
</div>
|
||||
<button @click="start">START</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -25,6 +40,8 @@ export default class App extends Vue {
|
|||
private readonly LFO_DEPTH = 33;
|
||||
private readonly LFO_OFFSET = 66;
|
||||
|
||||
private names = ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu"];
|
||||
private urls = Array(this.N_CHANNELS).fill("");
|
||||
private volumes = Array(this.N_CHANNELS).fill(50);
|
||||
private animateVolumeStart?: Date;
|
||||
private animateVolumeInterval?: number;
|
||||
|
@ -33,6 +50,12 @@ export default class App extends Vue {
|
|||
"https://www.youtube.com/watch?v=q76bMs-NwRk",
|
||||
];
|
||||
|
||||
private mounted() {
|
||||
this.defaultMedia.forEach((url, idx) => {
|
||||
this.$set(this.urls, idx, url);
|
||||
});
|
||||
}
|
||||
|
||||
private start() {
|
||||
(this.$refs.channels as Channel[]).forEach((channel) => {
|
||||
channel.start();
|
||||
|
@ -66,17 +89,52 @@ html, body {
|
|||
}
|
||||
|
||||
#app {
|
||||
font-family: monospace;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
|
||||
.channels-wrapper {
|
||||
display: flex;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.channels {
|
||||
display: flex;
|
||||
padding: 2rem;
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
.channel {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.channel-urls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.url-input {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.url-input label {
|
||||
display: inline-block;
|
||||
width: 64px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.url-input input {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.controls {
|
||||
padding: 2rem 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
<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="description">
|
||||
<div class="name">{{name}}</div>
|
||||
<div class="title">{{state === "loading" ? "Loading..." : title}}</div>
|
||||
</div>
|
||||
<div class="youtube-player" ref="ytpl"/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -32,6 +35,7 @@ enum ChannelState {
|
|||
|
||||
@Component
|
||||
export default class Channel extends Vue {
|
||||
@Prop() public name: string = "Channel";
|
||||
@Prop() public volume: number = 50;
|
||||
@Prop() public url: string | undefined;
|
||||
private youtubePlayer?: YouTubePlayer;
|
||||
|
@ -155,8 +159,7 @@ export default class Channel extends Vue {
|
|||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-family: monospace;
|
||||
font-size: 8px;
|
||||
font-size: 10px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
|
@ -170,7 +173,7 @@ export default class Channel extends Vue {
|
|||
|
||||
|
||||
.volume-wrapper {
|
||||
--height: 200px;
|
||||
--height: 180px;
|
||||
--width: 30px;
|
||||
height: var(--height);
|
||||
width: var(--width);
|
||||
|
@ -186,10 +189,15 @@ export default class Channel extends Vue {
|
|||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
.name {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: .25em 1em;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
|
|
Loading…
Reference in a new issue