[{"data":1,"prerenderedAt":58},["ShallowReactive",2],{"cms-projects-tv-shows":3,"cms-projects":20},{"title":4,"excerpt":5,"slug":8,"rawDate":9,"date":10,"content":11,"readingTime":12,"acf":13,"featuredMedia":19},"TV Shows App",{"raw":6,"plain":7},"\u003Cp>I like to keep track of the TV Shows I watch. I used to do this in a Word Document and manually go to IMDb and check whether the show was running or had been cancelled and then add the TV Show to my calendar. I decided to build an app that would do this for me. This was a good introduction to Svelte and Lambda functions.\u003C\u002Fp>","I like to keep track of the TV Shows I watch. I used to do this in a Word Document and manually go to IMDb and check whether the show was running or had been cancelled and then add the TV Show to my calendar. I decided to build an app that would do this for me. This was a good introduction to Svelte and Lambda functions.","tv-shows","2020-05-10T01:14:36",["Date","2020-05-10T00:00:00.000Z"],"\u003Cp class=\"wp-block-paragraph\">I like to keep track of the TV Shows I watch. I used to do this in a Word Document and manually go to \u003Ca href=\"https:\u002F\u002Fwww.imdb.com\u002F\" target=\"_blank\">IMDb\u003C\u002Fa> and check whether the show was running or had been cancelled and then add the TV Show to my calendar. I decided to build an app that would do this for me.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">I decided to try and learn a new framework whilst creating this fun little side-project. I’ve heard good things about \u003Ca href=\"https:\u002F\u002Fsvelte.dev\u002F\" target=\"_blank\">Svelte\u003Cpicture>\u003Cimg decoding=\"async\" loading=\"lazy\" width=\"16\" height=\"16\" src=\"\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=32\u002Fimg\u002Ffavicons\u002Fsvelte.dev.png\" alt=\"svelte.dev favicon\">\u003C\u002Fpicture>\u003C\u002Fa> so decided to give it a shot. It’s a framework very much like Vue (\u003Ca href=\"https:\u002F\u002Fjoebailey.xyz\u002Fblog\u002Freact-and-vue-re-visited\" target=\"_blank\">which I love by the way\u003C\u002Fa>). It splits it’s template files into CSS, HTML, and JavaScript which made it easy to get the hang of. It doesn’t come with something like Vue data, and there’s a weird thing where you need to tell the framework a variable has changed by doing \u003Cstrong>variable = variable\u003C\u002Fstrong>. Svelte devtools aren’t anywhere near as intuitive either. These small little things are the price you pay for infinitely better load times. All the processing is done in a compile step, whereas, Vue does all it’s processing in the browser. It’s a framework I’d go to for a simple static site that might have some components that are easier to create in a framework than with vanilla JavaScript. For most of my projects though, I’ll be sticking to Vue.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">My TV Show app is behind somewhat of a firewall, \u003Ca href=\"https:\u002F\u002Fteams.cloudflare.com\u002Faccess\u002F\" target=\"_blank\">Cloudflare Access\u003Cpicture>\u003Cimg decoding=\"async\" loading=\"lazy\" width=\"16\" height=\"16\" src=\"\u002Fimg\u002Ffavicons\u002Fteams.cloudflare.com.ico\" alt=\"teams.cloudflare.com favicon\">\u003C\u002Fpicture>\u003C\u002Fa>. I didn’t want the hassle of rolling an authentication system with my simple app so I decided to use Cloudflare Access instead. Otherwise, anyone would be able to add or remove TV Shows from my list. If you got to \u003Ca href=\"https:\u002F\u002Ftv.joebailey.xyz\" target=\"_blank\">https:\u002F\u002Ftv.joebailey.xyz\u003Cpicture>\u003Cimg decoding=\"async\" loading=\"lazy\" width=\"16\" height=\"16\" src=\"\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=32\u002Fimg\u002Ffavicons\u002Ftv.joebailey.xyz.png\" alt=\"tv.joebailey.xyz favicon\">\u003C\u002Fpicture>\u003C\u002Fa> you’ll see that you have to log in with Cloudflare first.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The app queries the&nbsp;\u003Ca href=\"https:\u002F\u002Fwww.episodate.com\u002Fapi\" target=\"_blank\">episodate API\u003Cpicture>\u003Cimg decoding=\"async\" loading=\"lazy\" width=\"16\" height=\"16\" src=\"\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=32\u002Fimg\u002Ffavicons\u002Fwww.episodate.com.png\" alt=\"www.episodate.com favicon\">\u003C\u002Fpicture>\u003C\u002Fa>&nbsp;when you perform a search and stores the added TV Show in a Fauna Database. It does this by using a Lambda function hosted on Netlify. There are also Lambdas for removing and viewing saved TV Shows. \u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The app then queries the Fauna Database for all currently watching TV Shows and fetches information on them from the episodate API. The TV show is green for currently airing. Red for cancelled\u002Ffinished. And has no colour for shows that haven’t announced new episodes yet.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The app exports all of the episodes set in the future to an iCal file which you can download and import into any calendar software. This is still a bit of a manual task and I wanted to automate it further so I created another Lambda function that fetches the TV Show information, and serves the calendar. This was quite a tricky process as I had to learn a lot more about Lambdas than just copying the FaunaDB examples. I got it working but it takes about 16 seconds to query all of the TV Shows I watch, longer than the 10-second execution limit on Netlify. I shopped around for another solution and came across Serverless, which makes deploying on AWS simpler. It only needs about 100mb of memory so I adjusted that limit accordingly.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">If I were to make this a production app I’d probably cache the API in Local Storage or in the Fauna Database and find a way of not having to query every TV Show when something is removed or added.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">If you want to get set up you can fork my \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FTV-Shows-Public\" target=\"_blank\">repository\u003Cpicture>\u003Cimg decoding=\"async\" loading=\"lazy\" width=\"16\" height=\"16\" src=\"\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=32\u002Fimg\u002Ffavicons\u002Fgithub.com.png\" alt=\"github.com favicon\">\u003C\u002Fpicture>\u003C\u002Fa> and add a .env file containing your FaunaDB secret. Or, if you want a Lambda function acting as a webCal you can fork that \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FTV-Shows-Calendar-Lambda-Function\" target=\"_blank\">repo\u003Cpicture>\u003Cimg decoding=\"async\" loading=\"lazy\" width=\"16\" height=\"16\" src=\"\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=32\u002Fimg\u002Ffavicons\u002Fgithub.com.png\" alt=\"github.com favicon\">\u003C\u002Fpicture>\u003C\u002Fa> and query any API you like. It uses \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fnwcell\u002Fics.js\u002F\" target=\"_blank\">ics.js\u003Cpicture>\u003Cimg decoding=\"async\" loading=\"lazy\" width=\"16\" height=\"16\" src=\"\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=32\u002Fimg\u002Ffavicons\u002Fgithub.com.png\" alt=\"github.com favicon\">\u003C\u002Fpicture>\u003C\u002Fa> to create the webCal. \u003C\u002Fp>",4,{"icons":14,"project_url":17,"github":18},[15,16],"Custom","Netlify","https:\u002F\u002Ftv.joebailey.xyz\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FTV-Shows",null,[21],[22,32,37,48],{"title":23,"excerpt":24,"slug":26,"date":27,"readingTime":12,"acf":28},"Notification of a delivery failure in Mailgun",{"plain":25},"When you use an email service provider like Gmail, you get delivery failure emails. These emails are great because it enables you to reach out to your intended recipient in another way, or just retry the email later on. Because I use Mailgun with Gmail’s Send Mail As feature for my custom domains, I needed […]","notification-of-a-delivery-failure-in-mailgun",["Date","2023-05-31T00:00:00.000Z"],{"icons":29,"project_url":30,"github":31},[15],"","https:\u002F\u002Fgithub.com\u002FGalexia-Agency\u002Fmailgun-failed-webhook",{"title":4,"excerpt":33,"slug":8,"date":34,"readingTime":12,"acf":35},{"plain":7},["Date","2020-05-10T00:00:00.000Z"],{"icons":36,"project_url":17,"github":18},[15,16],{"title":38,"excerpt":39,"slug":41,"date":42,"readingTime":43,"acf":44},"Weather app",{"plain":40},"My friend made a weather app so that they could learn APIs. I decided to fork it and take it a step further by experimenting with CSS Houdini, Variable Fonts, CSS Variables, and new browser APIs such as the Speech Synthesis API. Features This App uses experimental CSS Houdini features that are currently only supported in Google […]","weather-app",["Date","2020-02-01T00:00:00.000Z"],1,{"icons":45,"project_url":46,"github":47},[15],"https:\u002F\u002Fjoebailey26.github.io\u002FWeather-App\u002Findex.html","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FWeather-App",{"title":49,"excerpt":50,"slug":52,"date":53,"readingTime":43,"acf":54},"No Thumbnails Gallery",{"plain":51},"When creating my portfolio and memories page I needed a quick and easy way of creating galleries of images without having to code each individual image (there are over 3,000 images!). Also, I needed it without a thumbnail for each image. As far as I can tell there isn’t an easy option to do that. […]","no-thumbnails-gallery",["Date","2019-02-06T00:00:00.000Z"],{"icons":55,"project_url":30,"github":57},[56],"PHP","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002Fno-thumbnails-gallery",1793652638087]