Cleaned up dumbyt.ts a bit and fixed add channel
This commit is contained in:
parent
75be2c325e
commit
f757b5f519
@ -13,25 +13,33 @@
|
|||||||
<form v-cloak v-if="Expanded">
|
<form v-cloak v-if="Expanded">
|
||||||
<h2>Add new Channel</h2>
|
<h2>Add new Channel</h2>
|
||||||
<div class="grid-x">
|
<div class="grid-x">
|
||||||
<div class="input-group medium-6 cell">
|
<div class="medium-7 cell">
|
||||||
<span class="input-group-label">Title</span>
|
<p class="input-group">
|
||||||
<input class="input-group-field" type="text" placeholder="Title" v-model="Title">
|
<span class="input-group-label">Title</span>
|
||||||
|
<input class="input-group-field" type="text" placeholder="Youtube Channel Title"
|
||||||
|
v-model="Title" readonly>
|
||||||
|
</p>
|
||||||
|
<p class="input-group">
|
||||||
|
<span class="input-group-label">Channel ID</span>
|
||||||
|
<input class="input-group-field" v-bind:class="{ error: !Valid }" type="text"
|
||||||
|
placeholder="https://www.youtube.com/channel/UCJkMlOu7faDgqh4PfzbpLdg"
|
||||||
|
v-model="Channel_Identification_Box">
|
||||||
|
</p>
|
||||||
|
<p class="input-group">
|
||||||
|
<span class="input-group-label">Description</span>
|
||||||
|
<input class="input-group-field" placeholder="Description"
|
||||||
|
v-model="Description" readonly cols="15" rows="5"
|
||||||
|
type="text">
|
||||||
|
</p>
|
||||||
|
<button type="button"
|
||||||
|
class="button input-group" style="max-height:50px; max-width:100px; float: right;"
|
||||||
|
@click="Submit">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group medium-1 cell"></div>
|
<div class="medium-2 cell"></div>
|
||||||
<div class="input-group medium-5 cell">
|
<div class="input-group medium-2 cell">
|
||||||
<span class="input-group-label">Channel</span>
|
<img :src="Thumbnail"/>
|
||||||
<input class="input-group-field" v-bind:class="{ error: !Valid }" type="text"
|
|
||||||
placeholder="URL" v-model="Channel_Identification_Box">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="medium-1 cell"></div>
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-label">Description</span>
|
|
||||||
<input class="input-group-field" type="text" placeholder="Description" v-model="Description">
|
|
||||||
</div>
|
|
||||||
<div class="grid-x">
|
|
||||||
<img class="small-4 cell" :src="Thumbnail" />
|
|
||||||
<div class="small-7"></div>
|
|
||||||
<button type="button" style="max-height:50px" class="button input-group small-1 cell" @click="Submit">Submit</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</transition>
|
</transition>
|
||||||
@ -40,9 +48,10 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import * as Dyt from "../dumbyt";
|
import * as DumbYT from "../dumbyt";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
import SA2 from "sweetalert2";
|
import SA2 from "sweetalert2";
|
||||||
|
import * as _ from "lodash";
|
||||||
|
|
||||||
// Vue class for keeping state of the videos.
|
// Vue class for keeping state of the videos.
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
@ -63,10 +72,9 @@ export default Vue.extend({
|
|||||||
this.GetChannelFromYT(newcontents);
|
this.GetChannelFromYT(newcontents);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
Submit() : void {
|
Submit() : void {
|
||||||
Dyt.channel_modify(this.ID, Dyt.Modification.Add).then((resp) => {
|
DumbYT.API.channel_modify(this.ID, DumbYT.API.Modification.Add).then((resp) => {
|
||||||
if (resp == null)
|
if (resp == null)
|
||||||
SA2(
|
SA2(
|
||||||
"Channel Add Success!",
|
"Channel Add Success!",
|
||||||
@ -91,6 +99,11 @@ export default Vue.extend({
|
|||||||
this.Channel_Identification_Box = "";
|
this.Channel_Identification_Box = "";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Clear the contents of the add video field.
|
||||||
|
clear() : void {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
GetChannelFromYT(Channel: string) : void {
|
GetChannelFromYT(Channel: string) : void {
|
||||||
// Say it failed first so if we exit early then correctly marked fail.
|
// Say it failed first so if we exit early then correctly marked fail.
|
||||||
this.Valid = false;
|
this.Valid = false;
|
||||||
@ -113,9 +126,9 @@ export default Vue.extend({
|
|||||||
const API_Key = '&key=AIzaSyCuIYkMc5SktlnXRXNaDf2ObX-fQvtWCnQ'
|
const API_Key = '&key=AIzaSyCuIYkMc5SktlnXRXNaDf2ObX-fQvtWCnQ'
|
||||||
const API_Search_ID = '&id=' + this.ID;
|
const API_Search_ID = '&id=' + this.ID;
|
||||||
Axios.get(API + API_Parts + API_Search_ID + API_Key).then((resp) => {
|
Axios.get(API + API_Parts + API_Search_ID + API_Key).then((resp) => {
|
||||||
this.Description = resp.data.items[0].snippet.description;
|
this.Description = _.truncate(resp.data.items[0].snippet.description, {length: 70});
|
||||||
this.Title = resp.data.items[0].snippet.title;
|
this.Title = resp.data.items[0].snippet.title;
|
||||||
this.Thumbnail = resp.data.items[0].snippet.thumbnails.medium.url;
|
this.Thumbnail = resp.data.items[0].snippet.thumbnails.high.url;
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@ -124,3 +137,17 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.fade-enter-active {
|
||||||
|
transition: opacity 0.75s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter, .fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, {PropOptions} from "vue";
|
import Vue, {PropOptions} from "vue";
|
||||||
import * as _ from "lodash";
|
import * as _ from "lodash";
|
||||||
import * as Dyt from "../dumbyt";
|
import * as DumbYT from "../dumbyt";
|
||||||
|
|
||||||
// Vue class for keeping state of the videos.
|
// Vue class for keeping state of the videos.
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
@ -24,7 +24,7 @@ export default Vue.extend({
|
|||||||
// Searchbox updater with debouncing.
|
// Searchbox updater with debouncing.
|
||||||
searchbox_str (s: string) {
|
searchbox_str (s: string) {
|
||||||
var v = _.debounce((s) => {
|
var v = _.debounce((s) => {
|
||||||
Dyt.search_videos(s).then(videos => {
|
DumbYT.API.search_videos(s).then(videos => {
|
||||||
this.$emit('search_complete', videos)
|
this.$emit('search_complete', videos)
|
||||||
});
|
});
|
||||||
}, 400)
|
}, 400)
|
||||||
|
218
src/dumbyt.ts
218
src/dumbyt.ts
@ -1,10 +1,102 @@
|
|||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
|
|
||||||
// Base URL for API queries.
|
export namespace API {
|
||||||
const API_BASE_URL = "/api";
|
// Base URL for API queries.
|
||||||
|
export let Base_URL = "/api";
|
||||||
|
|
||||||
// How many chars at most for the description.
|
// Types of modifications which can be applied to various models.
|
||||||
const max_description_length = 100;
|
export enum Modification {
|
||||||
|
Add, Delete, Refresh
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change a channel state.
|
||||||
|
export async function channel_modify(youtubeID : string, modify : Modification): Promise<void | string> {
|
||||||
|
switch (modify){
|
||||||
|
case Modification.Add: {
|
||||||
|
let URL = API.Base_URL + '/Channels/' + youtubeID;
|
||||||
|
let resp = await Axios.post(URL).catch((error) => {
|
||||||
|
if (error.response)
|
||||||
|
return error.response.data;
|
||||||
|
else if (error.request)
|
||||||
|
return error.request;
|
||||||
|
else
|
||||||
|
return "Axios request failed for unkown reason.";
|
||||||
|
});
|
||||||
|
if (typeof resp == "string")
|
||||||
|
return resp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Modification.Delete: {
|
||||||
|
let URL = API.Base_URL + '/Channels/' + youtubeID;
|
||||||
|
let resp = await Axios.delete(URL).catch(e => console.log(e));
|
||||||
|
if (resp != null){
|
||||||
|
if (resp.status != 200)
|
||||||
|
return resp.data();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
return "Response is null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Modification.Refresh: {
|
||||||
|
let URL = API.Base_URL + '/Channels/Update/' + youtubeID;
|
||||||
|
let resp = await Axios.post(URL).catch(e => console.log(e));
|
||||||
|
if (resp != null){
|
||||||
|
if (resp.status != 200)
|
||||||
|
return resp.data();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
return "Response is null";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
console.log("Unknown request type, error ...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for channels based on a search string.
|
||||||
|
export async function search_channels(searchstr : string): Promise<Array<Channel>> {
|
||||||
|
// Temporary holder for data.
|
||||||
|
let Channels : Array<Channel> = [];
|
||||||
|
|
||||||
|
// Ask server for data.
|
||||||
|
let resp = await Axios.get(API.Base_URL + '/Channels/' + searchstr).catch(e => console.log(e));
|
||||||
|
|
||||||
|
// Handle all our nulls.
|
||||||
|
if (resp == null || resp.data == null)
|
||||||
|
console.log("server /api/Channels/" + searchstr + " return is null");
|
||||||
|
else {
|
||||||
|
// Parse our videos and add it to the video output.
|
||||||
|
resp.data.forEach((c: any) => Channels.push(new Channel(c)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send back the resulting videos.
|
||||||
|
return Promise.resolve(Channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for videos based on a search string.
|
||||||
|
export async function search_videos(searchstr : string): Promise<Array<Video>> {
|
||||||
|
// Temporary holder for videos.
|
||||||
|
let Videos : Array<Video> = [];
|
||||||
|
|
||||||
|
// Ask server for videos.
|
||||||
|
let resp = await Axios.get(API.Base_URL + '/Videos/' + searchstr).catch(e => console.log(e));
|
||||||
|
|
||||||
|
// Handle all our nulls.
|
||||||
|
if (resp == null || resp.data == null)
|
||||||
|
console.log("server /videos/ return is null");
|
||||||
|
else {
|
||||||
|
// Parse our videos.
|
||||||
|
resp.data.forEach((v: any) => Videos.push(new Video(v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send back the resulting videos.
|
||||||
|
return Promise.resolve(Videos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wrapper for channels returned from our server.
|
// Wrapper for channels returned from our server.
|
||||||
export class Channel {
|
export class Channel {
|
||||||
@ -90,121 +182,3 @@ export class Video {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types of modifications which can be applied to various models.
|
|
||||||
export enum Modification {
|
|
||||||
Add, Delete, Refresh
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change a channel state.
|
|
||||||
export async function channel_modify(youtubeID : string, modify : Modification): Promise<void | string> {
|
|
||||||
switch (modify){
|
|
||||||
case Modification.Add: {
|
|
||||||
let URL = API_BASE_URL + '/Channels/' + youtubeID;
|
|
||||||
let resp = await Axios.post(URL).catch((error) => {
|
|
||||||
if (error.response)
|
|
||||||
return error.response.data;
|
|
||||||
else if (error.request)
|
|
||||||
return error.request;
|
|
||||||
else
|
|
||||||
return "Axios request failed for unkown reason.";
|
|
||||||
});
|
|
||||||
if (typeof resp == "string")
|
|
||||||
return resp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Modification.Delete: {
|
|
||||||
let URL = API_BASE_URL + '/Channels/' + youtubeID;
|
|
||||||
let resp = await Axios.delete(URL).catch(e => console.log(e));
|
|
||||||
if (resp != null){
|
|
||||||
if (resp.status != 200)
|
|
||||||
return resp.data();
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
return "Response is null";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case Modification.Refresh: {
|
|
||||||
let URL = API_BASE_URL + '/Channels/Update/' + youtubeID;
|
|
||||||
let resp = await Axios.post(URL).catch(e => console.log(e));
|
|
||||||
if (resp != null){
|
|
||||||
if (resp.status != 200)
|
|
||||||
return resp.data();
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
return "Response is null";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
console.log("Unknown request type, error ...");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete a video.
|
|
||||||
export async function video_delete(youtubeID : string) : Promise<void> {
|
|
||||||
let URL = API_BASE_URL + '/Videos/' + youtubeID;
|
|
||||||
let resp = await Axios.delete(URL).catch(e => console.log(e));
|
|
||||||
if ((resp == null) || (resp.data == null)){
|
|
||||||
console.log("Video delete via " + URL + " FAIL");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for channels based on a search string.
|
|
||||||
export async function search_channels(searchstr : string): Promise<Array<Channel>> {
|
|
||||||
// Temporary holder for data.
|
|
||||||
let Channels : Array<Channel> = [];
|
|
||||||
|
|
||||||
// Ask server for data.
|
|
||||||
let resp = await Axios.get(API_BASE_URL + '/Channels/' + searchstr).catch(e => console.log(e));
|
|
||||||
|
|
||||||
// Handle all our nulls.
|
|
||||||
if (resp == null || resp.data == null)
|
|
||||||
console.log("server /api/Channels/" + searchstr + " return is null");
|
|
||||||
else {
|
|
||||||
// Parse our videos.
|
|
||||||
resp.data.forEach((c: any) => {
|
|
||||||
// Trim description if needed.
|
|
||||||
if (c.description.length > max_description_length) {
|
|
||||||
c.description = c.description.substring(0, max_description_length) + " ...";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add it to our array
|
|
||||||
Channels.push(new Channel(c));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send back the resulting videos.
|
|
||||||
return Promise.resolve(Channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for videos based on a search string.
|
|
||||||
export async function search_videos(searchstr : string): Promise<Array<Video>> {
|
|
||||||
// Temporary holder for videos.
|
|
||||||
let Videos : Array<Video> = [];
|
|
||||||
|
|
||||||
// Ask server for videos.
|
|
||||||
let resp = await Axios.get(API_BASE_URL + '/Videos/' + searchstr).catch(e => console.log(e));
|
|
||||||
|
|
||||||
// Handle all our nulls.
|
|
||||||
if (resp == null || resp.data == null)
|
|
||||||
console.log("server /videos/ return is null");
|
|
||||||
else {
|
|
||||||
// Parse our videos.
|
|
||||||
resp.data.forEach((v: any) => {
|
|
||||||
// Trim description if needed.
|
|
||||||
if (v.description.length > max_description_length) {
|
|
||||||
v.description = v.description.substring(0, max_description_length) + " ...";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add it to our array
|
|
||||||
Videos.push(new Video(v));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send back the resulting videos.
|
|
||||||
return Promise.resolve(Videos);
|
|
||||||
}
|
|
||||||
|
14
src/index.ts
14
src/index.ts
@ -5,7 +5,7 @@ import VTBL from "./components/Video_Table.vue";
|
|||||||
import CTBL from "./components/Channel_Table.vue";
|
import CTBL from "./components/Channel_Table.vue";
|
||||||
import CADD from "./components/Channel_Add.vue";
|
import CADD from "./components/Channel_Add.vue";
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import { Video, search_videos, Channel, search_channels } from "./dumbyt";
|
import * as DumbYT from "./dumbyt";
|
||||||
|
|
||||||
let MainApp = new Vue({
|
let MainApp = new Vue({
|
||||||
el: "#app",
|
el: "#app",
|
||||||
@ -21,12 +21,12 @@ let MainApp = new Vue({
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
Videos: Array<Video>()
|
Videos: Array<DumbYT.Video>()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// Callback for when the search component got results back.
|
// Callback for when the search component got results back.
|
||||||
search_completed(videos : Array<Video>) : void {
|
search_completed(videos : Array<DumbYT.Video>) : void {
|
||||||
this.Videos = videos;
|
this.Videos = videos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,18 +50,18 @@ let AdminApp = new Vue({
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
Videos: Array<Video>(),
|
Videos: Array<DumbYT.Video>(),
|
||||||
Channels: Array<Channel>()
|
Channels: Array<DumbYT.Channel>()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// Callback for when the search component got results back.
|
// Callback for when the search component got results back.
|
||||||
search_completed(videos : Array<Video>) : void {
|
search_completed(videos : Array<DumbYT.Video>) : void {
|
||||||
this.Videos = videos;
|
this.Videos = videos;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted(){
|
mounted(){
|
||||||
// Populate the channels field immediatly on start up.
|
// Populate the channels field immediatly on start up.
|
||||||
search_channels("").then(channels => this.Channels = channels);
|
DumbYT.API.search_channels("").then(channels => this.Channels = channels);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user