Woooo, functional video fetching using typescript!
This commit is contained in:
		@@ -1,23 +1,48 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div>
 | 
			
		||||
        <div>{{Videos}}</div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="grid-x large-up-6">
 | 
			
		||||
        <div v-for="video in Videos" :key="video.ID" class="cell">
 | 
			
		||||
            <div class="card ytcard">
 | 
			
		||||
                <a :href="video.URL"><img :src="video.Thumbnail"></a>
 | 
			
		||||
                <div class="card-section description">
 | 
			
		||||
                    <div class="descriptiontitle">{{ video.Title }}</div>
 | 
			
		||||
                    <div class="descriptionchannel">{{ video.Channel }}</div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div >
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import Axios from "axios";
 | 
			
		||||
 | 
			
		||||
// Wrapper for videos returned from our server.
 | 
			
		||||
class Video {
 | 
			
		||||
    // Title of the video according to youtube.
 | 
			
		||||
    public Title: string;
 | 
			
		||||
 | 
			
		||||
    // Description of video according to youtube.
 | 
			
		||||
    public Description: string;
 | 
			
		||||
 | 
			
		||||
    // Youtube ID
 | 
			
		||||
    public ID: string;
 | 
			
		||||
 | 
			
		||||
    // Thumbnail
 | 
			
		||||
    public Thumbnail: string;
 | 
			
		||||
    
 | 
			
		||||
    // What channel made this video.
 | 
			
		||||
    public Channel: string;
 | 
			
		||||
 | 
			
		||||
    // Duration of the video in seconds.
 | 
			
		||||
    public Seconds: number;
 | 
			
		||||
 | 
			
		||||
    // Tags relevant to the video.
 | 
			
		||||
    public Tags: Array<string>;
 | 
			
		||||
    
 | 
			
		||||
    // Youtube URL of the video.
 | 
			
		||||
    public URL: string;
 | 
			
		||||
 | 
			
		||||
    // Popuplate this using data from our server.
 | 
			
		||||
    constructor(v: any){
 | 
			
		||||
        this.Title = v.title;
 | 
			
		||||
        this.Description = v.description;
 | 
			
		||||
@@ -39,7 +64,6 @@ async function get_videos(): Promise<Array<Video>> {
 | 
			
		||||
 | 
			
		||||
    // Ask server for videos.
 | 
			
		||||
    let resp = await Axios.get('http://localhost:62214/api/Videos').catch(e => console.log(e));
 | 
			
		||||
    console.log("Got reply!");
 | 
			
		||||
 | 
			
		||||
    // Handle all our nulls.
 | 
			
		||||
    if (resp == null || resp.data == null)
 | 
			
		||||
@@ -61,17 +85,38 @@ async function get_videos(): Promise<Array<Video>> {
 | 
			
		||||
    return Promise.resolve(Videos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Vue class for keeping state of the videos.
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            Videos: Array<Video>()
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
        
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Ugh, vue doesn't have async support for computed, wow ...
 | 
			
		||||
    mounted() { get_videos().then(e => this.Videos = e ) }
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
    .ytcard {
 | 
			
		||||
        border-bottom-left-radius: 10px;
 | 
			
		||||
        border-bottom-right-radius: 10px;
 | 
			
		||||
        background-color:#ddd9d4;
 | 
			
		||||
        margin: 6px 2px 6px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .description {
 | 
			
		||||
        padding: 7px 5px 7px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .descriptiontitle {
 | 
			
		||||
        font-size: 14px;
 | 
			
		||||
        padding-bottom:10px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .descriptionchannel {
 | 
			
		||||
        font-size: 10px;
 | 
			
		||||
        text-align: right;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,26 +13,3 @@
 | 
			
		||||
    max-width: 960px;
 | 
			
		||||
    margin: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.curvedbottom {
 | 
			
		||||
    border-bottom-left-radius: 10px;
 | 
			
		||||
    border-bottom-right-radius: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tinytext10px{ font-size: 10px; }
 | 
			
		||||
.tinytext12px{ font-size: 12px; }
 | 
			
		||||
.tinytext14px{ font-size: 14px; }
 | 
			
		||||
.tinytext16px{ font-size: 16px; }
 | 
			
		||||
.tinytext18px{ font-size: 18px; }
 | 
			
		||||
 | 
			
		||||
[v-cloak] {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fade-enter-active, .fade-leave-active {
 | 
			
		||||
    transition: opacity 0.75s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fade-enter, .fade-leave-to {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user