diff --git a/scripts/youtube.py b/scripts/youtube.py index 1aad06b6..122202a6 100644 --- a/scripts/youtube.py +++ b/scripts/youtube.py @@ -34,6 +34,8 @@ class YoutubeChannel: channelCustomName: str channelName: str channelPic: str + channelPicH: int + channelPicW: int channelSubCount: int @@ -43,6 +45,9 @@ class YoutubeVideo: publishedAt: str videoId: str title: str + videoPic: str + videoPicH: int + videoPicW: int @property def published_dt(self): @@ -81,6 +86,9 @@ async def get_videos_from_channels(channel_ids: List[str], youtube: build): videoId=item["id"]["videoId"], channelId=item["snippet"]["channelId"], title=item["snippet"]["title"], + videoPic=item["snippet"]["thumbnails"]["medium"]["url"], + videoPicW=item["snippet"]["thumbnails"]["medium"]["width"], + videoPicH=item["snippet"]["thumbnails"]["medium"]["height"], ) channel_videos.append(video) @@ -135,6 +143,8 @@ def save_channel_data(channel_ids: List[str], youtube: build): channelPic=item["snippet"]["thumbnails"]["default"]["url"].split("=")[ 0 ], # Can set ?s= on the end to get a custom resolution + channelPicH=item["snippet"]["thumbnails"]["default"]["height"], + channelPicW=item["snippet"]["thumbnails"]["default"]["width"], channelSubCount=int(item["statistics"]["subscriberCount"]), ) channels.append(youtube_channel) diff --git a/src/lib/components/FilterForm.svelte b/src/lib/components/FilterForm.svelte index 90c8cfc3..7555f0f2 100644 --- a/src/lib/components/FilterForm.svelte +++ b/src/lib/components/FilterForm.svelte @@ -35,6 +35,7 @@ $: ({ filterOptions } = filterData) export let showFilterLogic: boolean = true + export let showReset: boolean = true // Whether all the selected tags must match the resource (vs any of the selected tags) let filterLogicAndCtrl: boolean = filterData?.filterLogicAnd ?? true let filterLogic: FilterLogic @@ -128,16 +129,18 @@ > {/if} - - - Clear All - + {#if showReset} + + + Clear All + + {/if} diff --git a/src/lib/interfaces.ts b/src/lib/interfaces.ts index 018fad02..194a283a 100644 --- a/src/lib/interfaces.ts +++ b/src/lib/interfaces.ts @@ -18,6 +18,8 @@ export interface YoutubeChannel { channelCustomName: string // e.g. "@notjustbikes" channelName: string // e.g. "Not Just Bikes" channelPic: string // e.g. "https://yt3.ggpht.com/5DBP22k02WIMvHgeoUj_Tt14Kh8u-oaAhYHQu1gXCoHuisGXnavb5k-ivpyffqIARNDzgpBbUw" + channelPicH: number // e.g. 180 (for 180px) + channelPicW: number // e.g. 320 (for 320px) channelSubCount: number } @@ -26,6 +28,9 @@ export interface YoutubeVideo { publishedAt: string videoId: string title: string + videoPic: string + videoPicH: number // e.g. 180 (for 180px) + videoPicW: number // e.g. 320 (for 320px) } export interface FilterOption extends Tag { diff --git a/src/lib/utils.test.ts b/src/lib/utils.test.ts index f8d00421..5f3e84ce 100644 --- a/src/lib/utils.test.ts +++ b/src/lib/utils.test.ts @@ -39,6 +39,8 @@ describe("YouTube Utilities", () => { channelCustomName: "climate town", channelName: "climate town", channelPic: "", + channelPicH: 180, + channelPicW: 320, channelSubCount: 2, }, { @@ -46,6 +48,8 @@ describe("YouTube Utilities", () => { channelCustomName: "FAKE1", channelName: "FAKE1", channelPic: "", + channelPicH: 180, + channelPicW: 320, channelSubCount: 100, }, { @@ -53,6 +57,8 @@ describe("YouTube Utilities", () => { channelCustomName: "FAKE2", channelName: "FAKE2", channelPic: "", + channelPicH: 180, + channelPicW: 320, channelSubCount: 270, }, { @@ -60,6 +66,8 @@ describe("YouTube Utilities", () => { channelCustomName: "FAKE3", channelName: "FAKE3", channelPic: "", + channelPicH: 180, + channelPicW: 320, channelSubCount: 5, }, ] @@ -85,6 +93,8 @@ describe("getChannelData", () => { channelCustomName: "climate town", channelName: "climate town", channelPic: "", + channelPicH: 180, + channelPicW: 320, channelSubCount: 2, }, { @@ -92,6 +102,8 @@ describe("getChannelData", () => { channelCustomName: "FAKE1", channelName: "FAKE1", channelPic: "", + channelPicH: 180, + channelPicW: 320, channelSubCount: 100, }, ] @@ -101,6 +113,12 @@ describe("getChannelData", () => { expect(res?.channelName).toBe("climate town") }) + + it("should throw error for no channel found", () => { + expect(() => getChannelData(ytList, "fake")).toThrowError( + `Channel ID with name 'fake' could not be found` + ) + }) }) describe("Emoji Utilities", () => { diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 3461d6b7..149e33fa 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -55,8 +55,13 @@ export const sortChannelBySubCount = ( export const getChannelData = ( channelData: YoutubeChannel[], channelId: string -): YoutubeChannel | undefined => { - return channelData.find((channel) => channel.channelId === channelId) +): YoutubeChannel => { + const channel = channelData.find((channel) => channel.channelId === channelId) + if (!channel) { + throw new Error(`Channel ID with name '${channelId}' could not be found.`) + } + + return channel } /** diff --git a/src/routes/youtube/+page.svelte b/src/routes/youtube/+page.svelte index f9e107c9..dfa05845 100644 --- a/src/routes/youtube/+page.svelte +++ b/src/routes/youtube/+page.svelte @@ -1,4 +1,6 @@

Climate YouTube

@@ -69,9 +87,10 @@ the latest long-form videos from each YouTuber. {#key rerender} @@ -81,7 +100,7 @@ {#each displayedVideos.slice(0, displayedVideoLimit) as video (video)}
  • diff --git a/src/routes/youtube/YoutubeThumbnail.svelte b/src/routes/youtube/YoutubeThumbnail.svelte index 6d2b444c..0d0bc377 100644 --- a/src/routes/youtube/YoutubeThumbnail.svelte +++ b/src/routes/youtube/YoutubeThumbnail.svelte @@ -1,70 +1,49 @@ - -