Categories
Uncategorized

Vote Like a Roman Emperor

Today my team launched our second WordPress block, the Vote block! The vote block lets your readers up or down vote content on your page that you’re looking for feedback on. You can already use it on your WordPress.com site or download the plugin for your self-hosted site here

What do you think?

Categories
Uncategorized

Either The Smartest or The Dumbest Thing I’ve Ever Done

That may be a bit of an exaggeration, but I’ve just imported the entire archive of my old blog at johncaruso.ca to this site. It was about 360 posts that date back to 2004 when I used to ramble on about mundane day to day things I was up to.

Its been fun to re-read some of those posts and reminisce, but at the same time, there are a bunch of formatting issues I now have to deal with since it was a completely custom site before and I had some weird css to make certain things (like code snippets) look just right. I’ll need to groom those posts and fix whatever needs fixing.

At the same time, it was a fun little exercise to generate a WordPress compatible XML file to export my old blog database to. Now I just need to generate the URL rewrites from my old site to point here so I can remove those posts from there and clean up that site a bit.

Categories
Uncategorized

Its A Poll Block!

My team over at Crowdsignal has been working on a cool new poll block plugin for WordPress called Crowdsignal Forms. We officially launched it this week for self-hosted WordPress sites and on WordPress.com! Please go check it out if you’ve got a WordPress blog or website.

Categories
App

Clean Your Clipboard!

The clipboard on my iPhone is something that I never really gave much thought to. Copy & Paste, it always just worked when it was there. It took until iOS 3 for it to be introduced, but since then, as a user, I never actually had to worry about it. That was until I installed the iOS 14 beta and I started noticing a new banner appear at the top of my phone whenever I pasted something.

I thought, that’s interesting, my iPhone is telling me when I paste something and where it came from. But then I started noticing it show up immediately after I opened certain apps. Apps that out of convenience would check my clipboard for me to see if there was, for example, a tracking number in there to automatically add it to my parcel tracking list. But that got me thinking, what if that was a password that I recently copied from my password manager? Would I want my post office to see the password to my email account or my company login? And while maybe I can trust my post office to not do something nefarious with what they see in my clipboard, are other apps so trustworthy?

So I decided to look into the feasibility of creating an iOS app that would read the clipboard (when you ask) and clear the clipboard at the tap of a button. After a few DuckDuckGo searches (I don’t Google anymore, more on that another time) and poking around in the Apple developer docs, it turns out its not that hard (literally 1 line of code for each action). So I downloaded the latest XCode beta and started putting together a simple iOS app with 2 buttons and a label, and I ended up with what I’m (for now) calling Clipboard Cleaner.

It is super simple right now, looks like trash, doesn’t even have an icon, but it works. It shows me whats in my clipboard if I’m curious, and clears it for me at the tap of a button. Its a bit of a nuisance since I have to open it before I can clear anything, so I’m thinking of adding some convenience features to make it a little easier to do (like a Siri shortcut, or maybe an iOS 14 widget).

I’m not sure if I’ll put this app up in the App Store or not, it works well enough for me as-is, and it would need a bit more polish before it would even make it through app review. And since I don’t really want to keep it to myself, and since its so simple, I’m making the code public so others can see, maybe learn, and since starting to work at Automattic I’ve been trying to embrace open source. And who knows, maybe someone will want to help add features to it, and it will hopefully get better being out in the open than hidden on my computer.

Check out the code! https://github.com/jgcaruso/clipboard-cleaner

But why stop there? I also thought I might want the same thing on my laptop. While other apps can probably sniff the clipboard whenever they want (not just when they’re opened), so its maybe less necessary to have, I wanted take a shot at creating a Mac menu bar app with the same features. Having no experience creating MacOS apps either I jumped back on DDG and found this fantastic article on creating a Mac menu bar app. It took a bit more finessing since the latest XCode beta has a new option for creating apps that the article didn’t mention (I needed to select AppKit from the Life Cycle dropdown), and the clipboard API has a different name, but other than that it wasn’t a huge fuss to put together. And so, Clipboard Cleaner for Mac was born.

Complete with source code! https://github.com/jgcaruso/clipboard-cleaner-macos

I’m looking forward to adding more to Clipboard Cleaner (and coming up with a better name), but I’m not sure on what kind of timeline. It feels good to have a small project I can poke at whenever I want, and to have something I made that I can take around with me in my pocket on my phone.

Categories
Web App

R2D2: A Messy Domain Tool

In the spirit of John making things, I’ve recently turned my gaze on the unnecessarily long list of domain names that I’ve collected over the years. I’ve moved between several different registrars at different times in the last 15 or so years, and have even spread out some domains in different places depending on the specific pricing and availability of non-standard TLDs like .be (for snpt.be, which was to be the url shortener for sniptube.com, a YouTube video concatenating site that I never actually launched).

The problem with having so many domains in so many different places is its hard to actually see what you have, and when they expire. The only time you really notice is when the registrar notifies you its up for renewal, and even then I may not pay attention because everything autorenews anyways.

As is my way, my attempt to solve this ‘problem’ wasn’t to just get rid of domains I don’t need anymore, or consolidate them on a single service (which won’t work for all domains because of pricing and availability… that pesky .be domain), but instead to build yet another web app.

Enter the Registrar Registry

I took a look at the different registrars I was using and 3/5 of them had APIs that I could use to query for a list of domains and expiry dates (the other 2 registries have been put on notice, and I’ll be switching off of them as the domains reach their expiry dates). So I started up vim (a new obsession of mine), created a new node/express app, and started making api requests.

I’ve decided to call this little app the Registrar Registry, and because it gives me Domain Data I’ve nicknamed it R2D2 (Disney, please don’t sue me). It connects to 3 of my registrars, pulls down my domain data and lists it out along with expiry dates, which I’ve beautified with momentjs to give me a nice human readable timeframe of when it is set to expire (expires in 15 days, expires in 9 months).

I’ve got this all up in a private GitHub repo that I’m planning on making public very soon incase such a tool would be useful to anyone else. And I’m hoping if it is, that this “someone else” might contribute a registry API connection if they happen to use a registrar that I haven’t added support for yet.

Categories
Coffee

The Roastery

I’ve been sitting on about 4 lbs of green coffee beans that I got as a secret santa gift at work last Christmas. I tried roasting on a skillet over my bbq this winter, but it was way too inaccurate and I just ended up burning the outside of the beans and not roasting the inside (which made something that caused my grinder to cry instead of making something drinkable).

I eventually got a proper roaster for my birthday and now I’m spending a couple nights a week sitting in my garage over this beautiful machine, breathing in the sweet smell of caramelizing sugars.

Its taken about 7 batches, almost 2lbs worth of beans, but I’m starting to get the hang of it. I’ve been keeping a detailed log of things like fan and power settings, time between changes of those settings and even outdoor temp which I started noticing has been affecting how fast the roast progresses. My roast this evening, which followed the exact same steps as my roast from last night, was ready a full minute earlier and the only difference was the outdoor temp was 3C higher.

I’m really hopeful for this evening’s roast, which for the first time had a decently audible first crack and ended with a pretty even medium brown colour (pictured first) vs my very first roast which is super uneven (middle) and my french roast (bottom) which wasn’t supposed to be a french roast but I got carried away listening to second crack and waiting for my timer instead of paying attention to the roast colour.

I’ve been keeping pretty good logs, and once I’m at a place where I can do things fairly predictably I’ll post my steps, favourite beans and tricks I’ve picked up along the way. For now, I’ve ordered a couple more pounds of green beans, including some Jamaica Blue Mountain as a reward and test for when I feel I’ve gotten good (well, good enough) at this.

Categories
Uncategorized

A New Beginning

I’ve had many web presences over the years. My first website (built with NetObjects Fusion and then Microsoft Front Page) was hosted on Geocities and it was a fan page for my heroes at the time: Patrick Roy, Saku Koivu and Jacques Villeneuve (if memory serves). After that I decided to learn HTML and build my first blog engine in java that would write out static files to be served. I then went on to learn PHP and mysql, built my own custom blog software and the rest is history. I’ve been building web apps ever since for fun and professionally.

And all that has lead up to where I am now, writing this first post on my newly minted WordPress.com site from the comfort of my sofa on the week and a half I have off between leaving my last job at Connected (which I thoroughly enjoyed but can’t speak too much about the super cool but secret projects I worked on there… damn NDA) and starting my next adventure with Automattic where I’ll be working on products for WordPress itself!

As I’ve said in the past, I’m going to try writing more. We’ll see how long it lasts this time around, but I think I’ll have quite a bit of content to go through before it starts to get tough. I’m going to try to write about my experience interviewing with and getting hired by Automattic as many have done before me, and also try to talk about what its like to work in a completely distributed company (oh yeah, I forgot to mention I get to work from home every single day).

I’m also going to try to import my existing blog’s content over here, but I’m not sure how that’s going to work with the existing links, so I may just leave things there and start fresh over here. I imagine JohnCaruso.ca becoming more of a portfolio site with links to all of my other stuff (including this blog). But we’ll see how that shapes up.

Categories
Uncategorized

Introducing: tiny nags.

Part of my self-re-education these last few months has been learning different web frameworks that I’ve been interested in but haven’t had the time to dive into. As you may have seen from my last post, one of those is ReactJS, and I’m proud to finally be able to make public the small project I put together while learning it… tinynags.com

tiny nags. is a web-based reminders app that uses HTML5 browser notifications to ‘nag’ you to do things that you need reminding. I created a few cute little robot characters to give the site a bit of character and not look as boring as it sounds. It supports all modern desktop web browsers (although some with limited support due to html5 notifications not being implemented the same across different browsers and operating systems) and Chrome on Android which was a nice little freebie I got for supporting HTML5 service workers. Safari on iOS doesn’t have support for HTML5 notifications so it has been left out in the cold. I may turn this into a mobile app at some point if I have the desire to, or if there is enough demand.

I’m currently trying to promote the site by contacting various productivity blogs and have posted it up on reddit here so if you have a Reddit account, please upvote it for me!

Categories
Uncategorized

Piggy Backing on ReactJS’s ServiceWorker for Notification Event Listeners

About a week ago I decided to start learning ReactJS because why not? just to get some exposure to yet another javascript framework that seems to be pretty popular right now. I had been in the middle of putting together a notification/reminder web app (more on that in a later post) and wasn’t particularly happy with the code I ended up putting together to populate the UI. Fast forward to yesterday, I gained some rudimentary knowledge on how to use React, converted my existing jquery based web app to React (along with my ServiceWorker code that was detecting when a notification was clicked or closed) and I was now ready to do a production build of the app. Upon doing the build and testing the resulting site, I found out that my service worker code was no longer firing.

After doing some digging I found out that React uses its own service worker to enable itself to run when your browser or device is offline. I was thrilled that I got that for free out of the box, but it also meant that my service worker was no longer running since you can only have 1 service worker running at a time for a single URL scope.

My solution for this was to merge my service worker code in with React’s service worker. Just a warning: This may not be recommended by React, and it might only work for my particular case because I just need to add some event listeners to the service worker. Your mileage may vary.

Since I was no longer able to run any code during the register phase of the service worker (since React is doing the registration), I needed to do the following in order to get a reference to the registration object whenever I want to call showNotification()



navigator.serviceWorker.ready.then(registration => {
    registration.showNotification("Notification Text",
    {
        data: {
            id: "recordid"
        }
    });
});

On the service worker side, I just need to paste in my event listeners into the service-worker.js file in the /build directory after building the React project. Keep in mind, you will need to do this every time you re-build your React project since that file will get replaced.



self.addEventListener("notificationclick", handleClickClose)
self.addEventListener("notificationclose", handleClickClose)

function handleClickClose(event) {
    const n = event.notification;
    sendMessage(n.data.id)
    n.close();
}

And thats all there is to it! You might notice that I’m calling a method sendMessage() in my event handler. I’m using this to let my application know which notification is being acted on. It isn’t required for the event handler to work, but it is part of the functionality for the web app I’m working on. sendMessage() is implemented as follows:



function sendMessage(pstrMessage)
{
    clients.matchAll({includeUncontrolled: true, type: 'window'}).then(clients => {
        clients.forEach(client => {
            client.postMessage(pstrMessage)
        })
    })
}

And I have an event listener that is registered during componentDidMount() in my React app’s root class that listens for messages from the service worker:


navigator.serviceWorker.addEventListener('message', function(event){
     // do some work here
     console.log("click notification for " + event.data)
});

Just one final note, I wrapped the registration of my original service worker in an if statement that checks if I’m in dev mode or not. This way it will still register during development (since the React service worker isn’t registered) and it is prevented from registering in production.



if (window.location.port === "3000")
{
     navigator.serviceWorker.register('/sw.js').then(...)
}

I imagine if I was better versed in React and building npm packages that there might be some way to bundle this up into a cleaner package that would make it more reusable and tie into the React build process in order to skip the manual step of copy/pasting the event listeners into the service-worker.js file. If anyone stumbles on this article and has knowledge of how to do that please let me know!

Categories
Uncategorized

New iOS App In The Works

My first foray into native (non Cordova) iOS apps has been in the works for the last couple of weeks. I read through Matt Neuburg’s iOS 10 Programming Fundamentals with Swift and Programming iOS 10 (although I cherry picked the parts I thought I’d need in this one) and then got started writing my first app, tentatively titled WallpaperCapture; A camera app that lets you take a photo for your iPhone lock screen and home screen with all of the labels and objects you’d normally see superimposed on the screen so you can frame the scene perfectly.

The goal with this app right now isn’t to get rich (I’m going to release it for free, possibly ad supported) but rather to practice what I’ve been learning, and experiment with interface objects and frameworks that I’ll likely need in the future on a much larger project. I’ve got a preliminary build that I’m testing right now that provides the time, date and other lock screen labels of an iPhone, along with the Perspective Zoom so that the photo that you take will look exactly as it does when you set it as a lock screen photo. The photos are currently stored into an app specific album in the Photos app, but I’m planning on having an in-app library to see all of the photos that have been taken. Eventually I will provide a way to upload the best images ‘to the cloud’ so that the photos can be shared with other users looking for interesting and unique wallpapers.

I’m in the process of implementing Fabric.io’s Crashlytics for app statistics prior to releasing the app to some users via TestFlight (email me if you are interested in being part of the beta test group). Once that is done and I’m ready to implement the ads and photo upload, I think I’m going to integrate with Firebase since it is an all in one SDK for ads, cloud storage and countless other features that I may need in the future.