Cos they sucked me into a free trial and charged my card a year later without my realising. I didn’t even know I was subscribed.
Further, as an Australian there’s no way to contact them because they work on US business hours. So I was up at 2AM the other night hanging off a chat box where Vincent was apologetic, but kept pasting prefabricated blocks of text telling me to get fucked.
It’s enshittification at its best. They’re beholden to investors, and have to invent junk services to get that sweet recurring revenue. And their policy is no refunds, ever. So it’s obviously deliberate.
So basically, fuck em.
Insta360 and DJI both have excellent products in this space that may have their own ideological foibles, but at least won’t brazenly steal money from your card.
Google Maps like much of the web has devolved into an AI generated slurry.
Nowadays every review I leave gets a reply “from” the business which is clearly generated by a machine. All the photos are inevitably going in to train Gemini. And the level-up gamification was fun at first but led to nothing more than endless grinding to reach the next level.
Anyway, I’m out. Have been for a little while. But I’ve left a trail of photos and digital detritus I’d rather clean up.
Google doesn’t have a way to bulk-delete your stuff (for obvious if annoying reasons) so I thought I’d write a little script to do it for me.
The scripts
There’s two scripts, one for photos and one for reviews. They’re pretty naive and need to be restarted from time to time but they should be safe enough.
Huge disclaimer: these will probably get out of date at some point and may not work. You should read and understand the code before you do anything with it.
For photos, make sure you’re on the “Photos” tab of the My Contribution section (see above), then I ran the following in the console:
(async () => {
const sleep = (time) => new Promise(resolve => setTimeout(resolve,time));
const go = async () => {
// click the kebab
document.querySelector('button[jsaction*="pane.photo.actionMenu"]:not([aria-hidden="true"])').click();
await sleep(200);
// click the delete menu item
document.querySelector('#action-menu div[role="menuitemradio"]').click();
await sleep(200);
// click the "yes I'm sure" button
document.querySelector('div[aria-label="Delete this photo?"] button+button,div[aria-label="Delete this video?"] button+button').click();
await sleep(1500);
// check if there's any left, and do it all again
if(document.querySelector('button[jsaction*="pane.photo.actionMenu"]:not([aria-hidden="true"])')) go();
}
go();
})()
And for reviews on the reviews tab:
// delete reviews from Google Maps
(async () => {
const sleep = (time) => new Promise(resolve => setTimeout(resolve,time));
const go = async () => {
// click the kebab
document.querySelector('button[jsaction*="review.actionMenu"]:not([aria-hidden="true"])').click();
await sleep(300);
// find the delete review menu item
const deleteMenuItem = document.querySelector('#action-menu div[role="menuitemradio"]+div');
if(deleteMenuItem.textContent.trim() !== 'Delete review') return console.error('wrong menu item', deleteMenuItem.textContent);
deleteMenuItem.click();
await sleep(300);
// click the "yes I'm sure" button
document.querySelector('div[aria-label="Delete this review?"] button+button').click();
await sleep(2000);
// check if there's any left, and do it all again
if(document.querySelector('button[jsaction*="review.actionMenu"]:not([aria-hidden="true"])')) go();
}
go();
})();
These are also on Github because my blog code formatting isn’t great. I should fix that up sometime.
What I learned hacking Google Maps (lol)
This code is pretty naive, and breaks a lot. I had to go back in a few times to restart the script, or adjust the timings when something broke. But it got there in the end.
I do appreciate the simplicity of the sleep() function/promiseified setTimeout. This isn’t in the language because it’s generally better to attach some kind of event or observer or do some polling to make sure the app is in the correct state. But in this case I thought it was a fairly elegant way to hack together a script in 5 minutes.
I could make this faster and more stable by implementing some kind of waitUntil(selector) function to await the presence of the menu/dialog in the DOM. But I would also need a waitUntilNot(selector) to wait for the deletion to finish. In any case that’s more complex, and we don’t need to overengineer this.
Anyway, the second script is done now and all my photos and reviews are gone. I’m still somehow a level 6 local guide (down from a level 7) so good for me.
I’ve been thinking a lot about the problem of garbage AI generated content on the web. It’s a problem that erodes trust and makes everyone look bad. So how do you combat that?
Web buttons, of course!
I took a minute to make a colourful web button, I hope you like it.
These were popular in the early 2000s as a way of adding pieces of flair to your website, to link to friends, and to show off your W3 validated XHTML and CSS.
And given my web site is of a certain vintage I thought I’d do something up in the style.
I think it worked out really well. The little robot is very cute, and the colours were kind of inspired by the old Amiga button. And as was common at the time I exported it and closed before remembering to save my sources, so this is it now.
If you want to download and use the button on your own website, go for it. It’s all yours. Use it as you wish:
I’ve decided to upscale it here for effect, but the original version is indeed 88×31 pixels.
If you want to upscale it, you can add the css image-rendering:pixelated; to make it render pixel perfect, rather than using a more blurry modern scaling designed for photos.
We’re releasing a WebGL feature soon, and let me tell you Safari has lived up to its reputation as the new Internet Explorer.
We’ve had two big issues:
Safari completely crashes the tab with “a problem repeatedly occurred”
Safari WebGL rendering flickers when scrolling the page
Safari completely crashes the tab with “a problem repeatedly occurred”
The most concerning issue was the Safari crash, which only happened on iOS, not the simulator. I don’t have any iOS devices to test with, so I made the decision to get myself an iPad mini. It’s a write off!
After debugging for way too long, I worked out this was a memory usage issue. Even though Safari runs on some of the most powerful mobile hardware around, it has a hard limit on how much RAM a web page can consume. Even when that page is open. So you can’t make full use of the device in Safari.
My problem had several causes:
I was loading multiple WebGL interactives on page load. Deferring these until the user scrolls them into view helped fix the issue.
I was caching WebGL textures to make the interactive feel snappier. In the end I had to remove all the caching optimisations to get under the Safari memory limit, and now each texture is rendered in realtime when it’s needed.
On top of this, I was hitting an issue with too many layers in Safari causing excessive memory usage.
Compositing layers are created when animation happens in your page. Much like old cel animated films, the browser keeps content that isn’t likely to change in separate layers so it can sandwich animated layers in between, without having to draw everything all over again. For instance a parallax effect will have a background layer and a foreground layer, moving at different speeds.
An example of animation layers drawn on old school cel sheets. The pink panther can be added and removed from the scene without redrawing the layers underneath. Via The Art Professor.
Layers in Safari are created by a number of things, including:
3d transforms – e.g. -webkit-transform: translateZ(0);
Canvas layers – canvas is designed to be drawn and redrawn at arbitrary times, so the browser keeps it on its own layer.
position:sticky/position:fixed – similar to parallax effects, these are just a part of doing business and we can’t optimise them any further
In our case, we had a number of 3d transforms and unnecessary will-change properties creating extra layers. These were contributing to Safari crashing. Cutting down on these layers stopped our page from crashing.
Safari WebGL rendering flickers when scrolling the page
This one was killing me because I couldn’t reproduce it on the iPad, and I don’t have an iPhone to test on.
This mostly seemed to happen in in-app browsers (like Slack), but this morning a colleague was able to reliably reproduce it in Safari proper, and I was able to reproduce it in the simulator.
It only seemed to happen while scrolling text boxes over the WebGL canvas So my assumption was that something was clearing the canvas without drawing the scene back in. The app is creating a separate offscreen WebGL instance for performing calculations and I assumed it might be some sort of weird race condition.
I tried a number of fixes that didn’t help:
Render every frame, regardless of whether render is needed (i.e. don’t pause rendering when the scene hasn’t changed. Based on this similar bug).
I tried enabling preserveDrawingBuffer in the renderer, because it seemed related. No dice.
Disable anti-aliasing (per this bug, where Mapbox GL and Three.js fight it out in the same WebGL context)
Downgrade to WebGL 1 (instead of 2). I can’t find the original post suggesting this, but it didn’t do anything.
The actual bug in my case was completely unrelated to Three.js.
When the screen resizes, I update the canvas size, the camera aspect, and projection matrix so that the canvas scales to fit its new dimensions:
The problem is that this code doesn’t rerender the scene. So after it’s run the frame is left blank until the next requestAnimationFrame runs.
This wasn’t a huge problem, except when the Safari chrome disappears off the page the browser triggers a whole bunch of resizes in rapid succession. These were resizing the scene, and resulted in black frames until the scene rerendered, multiple times per second. And it didn’t happen on the iPad because the chrome never disappears offscreen.
Adding a this.renderer.render() to the resize function was a somewhat inefficient but effective fix.
I have two weeks off so I’m spending the giftmas period with my parents. It’s hot, and I’m sitting on the veranda while Charlie pesters me to throw the ball. There’s a decent breeze, but it looks like we’ve missed the storms.
Dark mode fix: I fixed a bug on the site where it was always defaulting to dark mode. It’s been that way since I first implemented it because I was checking the truthiness of window.matchMedia("(prefers-color-scheme:dark)") instead of the boolean window.matchMedia("(prefers-color-scheme:dark)").matches. It should now respect your system preferences, and you can use the little icon in the bottom right to toggle between them.
Missing images: The backend of this site is running on WordPress, and there was a period of time where I was using it to photoblog. Anyway, some of those posts only contain a featured image and nothing else, and the featured image wasn’t showing up on this frontend site. So now feature images will show unless they’re already elsewhere in the post.
Dessert upgrade: I have acquired my mum’s family trifle recipe. It’s not beautiful, but it is my favourite. We made it together on xmas eve, and I’m so happy with it.
Hardware acquisition: I placed a late night ebay bid on an old Thinkpad and put Arch Linux on it, inspired by Josh‘s recent blogging. It’s a lot of fun and even though it’s a few years old, it’s way faster for day to day tasks than my M1 mac. Obvs not for video work, but I want to use it to get back into vector art. Though I see the Arch community has AURs for DaVinci Resolve which is shockingly difficult to get running on Linux, so I might dust off my desktop and put it on that as well.
Beyond that I made rum balls in my parents Thermomix and they came out alright. I blitzed up some almonds for a bit of health, and I think I’m gonna start making protein balls at home as a healthy snack. Do you have any good recipes?
I’ve also booked accommodation for my second week of holiday so I’m gonna take my new bike for a spin out to Bribie Island for a few days. No vlog cos it’s gonna be public holiday and kids everywhere. But I’ll post some bits on Mastodon.
I know people have been on this bandwagon since the start of the panini, but by bread making adventures are more out of necessity.
I like bread. But I’m not a big sourdough man. I want something light and fluffy to put cheese and cold cuts and salad on. Maybe a little peanut butter. But living in a gentrified neighbourhood, the options are stark.
The Aldi down the road is abominable. Bread from Aldi is made off-site before being shipped in, and in my experience it’s stale before it’s even put on the shelves.
The cheap Woolies bread is decent, but the store has staffing issues. Recently the sole baker went on leave. I don’t begrudge them that, but it meant there was no fresh bread on the shelves, and it had a flow-on effect to other supermarkets nearby. Fresh bread became impossible to get!
Then there’s the French patisserie around the corner. I’ve tried their baguette a few times and it’s alright, but it’s crusty enough to cut your teeth on. I don’t like bread that leaves sore bits in your mouth for the rest of the day so it’s really only an occasional thing.
So at my wit’s end I’m making fresh bread.
Japanese Milk Bread
It started with a message from Ben (as it often does):
Milk bread is not the easiest bread, especially to start with, so I’m told. But I was sitting around at my parents’ place with an idle Thermomix and little else to do so I figured I’d give it a shot.
The tricky part of milk bread is the tangzhong, which is a paste of cooked flour and milk. Wikipedia says it improves the texture of the bread, and also “stabilizes the wheat starches in the bread, to prevent recrystallization” which stops it going stale.
The recipe had Thermomix instructions for the first steps. I have a bit of a love-hate relationship with the Thermie because the recipe paywall stuff is a nuisance when trying to find a recipe, and it’s kinda hard to deviate from a set plan. But this one was a custom, non-wizard affair so it was fairly easy to follow. The trickiest part was finding the “dough” setting — apparently it just spins the blades backwards rather than having a specialised dough hook.
As it was my first time making bread, and it seemed to take forever, because I was hanging on every step of the recipe. Peering at the Thermie waiting for the temperature to get just so. Waiting around for the bread to prove. I didn’t want to leave it, in case it grew legs and ran off.
But the results were great. The bread was true to its tangzhong: soft and fluffy and kind of set my bar high for the rest of my bread making career.
Making bread with a Ninja
At home I don’t have a Thermomix, but I do have a Ninja Foodi Power Blender and Processor System which comes with a dough hook. So I got myself a loaf tin, and tried to recreate the magic.
The Ninja was a bit fiddly on the dough setting. The program runs for exactly one minute and it rattled all over the bench so I needed to hold it down. It seemed super quick for a bread loaf so I ran it again and it went into some kind of shutdown protection mode, presumably because the motor was working too hard.
I later found out you’re supposed to manually break the dough up before running it again, which helps the food processor process it. But even with one and a half runs, the bread came out super impressive for a second attempt.
I don’t know about you, but a thick-cut milk bread grilled chicken burger is exactly the thing I want.
Soft white bread is too hard
Having mastered the milk bread, and truth be told gotten a little sick of it, I turned my attention toward white bread.
And so I set out confidently on my next bake. Little did I know it would be my undoing.
I don’t know exactly what went wrong, but it was probably a combo of:
I got scared of the Ninja dough setting burning the motor out, so I only did one run of the kneading. That’s 60 seconds, which is probably much too short.
It’s summer, and we’ve been in a heatwave so the temperature has been pretty high and they may have proved too fast.
I think I probably let them prove too long, because:
They immediately deflated in the oven. The first attempt came out like a long flat bread brick. It was edible, but highly questionable.
The second time I tried to prove in the fridge to try to account for the heat variable. It didn’t seem to do much.
And to make matters worse, I took it out of the oven too soon so it was still raw in some parts. I’m not even going to show that one because it was a disaster.
Thankfully Shawn was here to help eat the edible bits. And it was tasty! But a fair bit of it went in the bin.
So even though that was only yesterday I thought I’d give it one more try. This time I:
Ran the dough through the food processor several times. It came out a much better, springy consistency.
Didn’t fuck around while proofing. I let it go for 30 minutes the first time, and another 40 minutes the second time.
Gave it a bit of a bash to make sure it wasn’t going to collapse before putting it in the oven. It stayed solid.
Got overly excited and underbaked the damn thing again lol.
When the bread didn’t sink, and started to crust up on top I was ecstatic.It’s golden brown. In places.
So I sit here staring at my still slightly-flat loaf cooling on the rack. Apparently allowing the bread to come to room temperature rather than tucking right in “optimizes texture and flavour, and there are several theories as to why“. So I’m gonna leave it go.
Several hours later
I cut the bread and to my surprise it actually looks like bread.
It’s still a touch heavy, but the texture is about right. One jam and peanut butter sandwich later I’m content.
I still don’t entirely know what went wrong with the others, but the extra kneading and possibly the quicker proving time made a difference. Next time I’ll just have to keep it in long enough for a bit more colour. And I think if I want it to be any taller I might need to multiply the recipe.
I’m not sure how to get it fluffier but apparently there are various types of tangzhong that can help get more moisture in, so I might try that next.
Anyway if you have any ideas, hit me up. I’m keen to hear your tips and tricks. You can reply to this thread on Mastodon or just shoot me an email.
I now have the trifecta of wifi at home, work, and my parents place. So I just ordered the cheapest $100/year Kogan/Vodafone SIM and I’ll activate it when my Telstra prepaid runs out next month. You can’t beat those kinds of dollars.
I’ve been at my parents all week for assorted reasons. Just finished the drive home.
I got pulled over by a police man on a motorcycle on the way back and given a fine because my bike was obscuring the number plate. He didn’t want me to fix it or anything, just a fine. So that’s cool. That’s $125 bucks going towards… I don’t know, what does that even contribute to?
I’m exhausted. It feels like perpetual Sundays afternoon.
Some of my plants are dead, some of them are double the size.
I’ve collapsed on the couch, I fear I may never get up again.
On Saturday I woke up with a vague sense of unease and decided to fix it by cleaning the house. Kitchen, laundry, bedroom, floors. I didn’t have anywhere to be so as I noticed tasks I did them, and it left my place feeling like a great space to be.
It’s been feeling like spring for most of winter, it’s been a very mild one. But nevertheless the sun has swung around and I’m getting more light in my place now. I can leave my doors open (screens closed) to let air circulate, and the plants are having a great time.
It is a time of optimism and, well, occasionally having to put that climate anxiety back on the shelf. But largely optimism.
Riverfire 2023
I didn’t get up to much during the day but in the evening I decided to head out to watch the Riverfire fireworks.
It’s usually packed in South Bank and everywhere really, so I though I’d roll around on my bike and find a spot. Turns out the Kurilpa Bridge was open and you could just hang out and watch from there. I didn’t have an amazing view, but it was a nice $0 activity that took almost no effort on my part.
On the way home I stopped at the William Jolly Bridge because there’s a light installation underneath now. That night it was lit in rainbow colours and looked fetching in the eerie firework smoke.
Ben came over and we went to Banette, the little French bakery.
They revamped their menu and they’re providing table service now so it’s a proper place to dine out. I was really happy to see their sad and crusty Croque Monsieur from the hot box is now freshly made, along with a number of other breakfasty options.
So we had brunch for lunch. It was pretty great. I don’t imagine I’ll get this too often, but it was a decadent but not too heavy option and the greenery really rounded it out. I’m very pleased.
After that we went on a nursery crawl and looked at all the plants.
I’m trying to be a bit frugal since I changed jobs and accidentally went 6 weeks between proper pay cheques, so I only picked up a couple of little friends and a colourful pot because I need to re-pot one of my plants.
But Mappins also has fish and they were very cute and I really wanted to take one home with me. That might be a separate project needing a bit more research, but I reckon it could be a good hobby.
Shawn stayed at my place the night before, so we could wake up and leave first thing. The sun came up as we drove across the border to NSW, spreading sunbeams across the farmland and leaving misty gulleys where the light didn’t reach. The mountains were beautiful, but truth be told there wasn’t much to see from the highway.
We arrived in Coffs at about 9AM and made a beeline to what turned out to be the greasiest, fingerprint-covered Maccas I’ve ever been in. We got McMuffins and headed down the road to the closest beach we could find.
I didn’t bring swimwear or a towel because the forecast was for overcast and rain all weekend. To be fair, there was a little bit of cloud when we arrived, but it cleared out soon enough to reveal blue skies and a high UV index that continued for the entire trip.
After McMuffins, sunscreen, going back to the car to fetch hats, and sitting on the beach watching the crabs for 53 minutes (according to my Google location history), we set off on a walk.
Coffs surprised me with the amount of walkways and free things to do. I’d only ever passed it from the train. It looked like a nice beach and a handful of banana plantations and that’s it. But the coastline is full of parkland and beaches, and all linked together with a nice wide path that extended further than we were willing to walk.
This is the rail bridge where you see the coast for the first time, on the Brisbane to Sydney train. It’s ugly but I like it a lot.
We managed a couple of kilometres to the marina, and poked around the artificial breakwater before reaching Muttonbird Island
The island is attached to the mainland by the marina these days, but is still an important nesting ground for the little birds to dig holes in the ground and raise their chicks. There’s a designated walkway from one end of the island to the other, and signs warning you not to stray, lest you step on a sleepy bird. Or break an ankle.
We didn’t see any birds, I think we were a bit late in the season. But I appreciated the cliffs, and sat mesmerised by the overwhelming power of the ocean smashing against the rocks. And there was a pretty cool ocean bird hovering in the air for most of the time we were climbing the island again to get back to dry land. (Black wingtips, not sure what it was.)
Our inappropriate choice of clothes made for an uncomfortable walk, so we started back to the car to check into the hotel. But we stopped at the surf lifesaving club for lunch first. I had a parmi and Shawn had a chowder.
I saw they had Schweppes behind the bar so I asked if they had Pepsi Max, and the man said no, but the other girl said she prefers Pepsi Max, and the man asked if there’s a difference and we both said YES! and he said maybe they should switch from Coke No Sugar.
This conversation continued every time I went to the bar, and also when he came around at closing time (2:30) to pack up the tables. We had a rapport.
Check-in was easy enough. The place was 90s vintage, but pretty clean and had an amazing view of the ocean, islands, heritage lighthouse etc. The lighthouse came to be my main wayfinding point throughout the trip.
The window between the bedroom and the toilet was an unusual choice, but we devised a roster system to prevent surprises.
That afternoon we sat on the balcony and ate far too much, watching the myriad of bird life screech and warble and do its thing. There were two tourist planes as best I could tell; one dropping off paragliders, and the other one just hanging around in the sky soaking up the sights.
The main gotcha was the lack of wi-fi. Despite the blinking modem on the counter, the lady at the front counter said it stopped working and they removed it from the listing. And lo, turns out I’d booked a place without internet.
That night we tethered to my one bar of Telstra and watched Miriam Margolyes reluctantly trudge around Australia and be grumpy in standard definition.
We decided we didn’t need to spend a whole bunch of money on holiday, so we stocked up on supplies and made sausage & egg muffins again for brekky.
We took them to Moonee Beach and grabbed hot chocolates from the cute coffee shack by the beach called I Bean There, and sat watching the surfers, dogs, and hilariously the kids trying to ride their bikes through the sandy creek.
I spilled chocolate all down my nice white shirt, but it mostly came out with wet wipes.
After brekky we drove up to Korora Lookout. It’s a public access lookout with indigenous significance. There’s a little pedestal to read aloud the story of the area, and a cunty next door neighbour who’s planted bamboo along the edge of their property to stop people enjoying the view.
This was where I saw my first leech: a little inchworm-looking thing attached to the sole of my shoe. I knocked it off, and we both hiked our socks.
We walked to the second lookout, with a purpose built suspension deck that some dude thought would be funny to make swing while we were all standing on it. The views were amazing and I tried (but failed) to spot the train line into town.
We stayed for a moment before setting off on a bushwalk into what I refer to as leech gully (side note, that’s what Indooroopilly means. It’s a corruption of the Yuggera language.)
We started trekking down the hill in a nice moist rainforest setting. We were planning to take the trail a couple of kilometres out, but as we descended and the path got thicker with foliage. The sunlight disappeared. Fern fronds brushed past our legs.
That’s when we saw them.
Mother and two kids making their way out of the forest, looking stricken.
“Turn back!” she said, with fear in her voice.
“The leeches have leeches!”
One of the kids had blood streaming down his leg.
We tried to make it to the next clearing, but I freaked out. Shawn wanted to go ahead, but I couldn’t enjoy a hike when there’s blood sucking parasites waiting to hitch a ride.
We turned back and took the shorter, better maintained path in a little loop back to the lookout.
From there we drove to Sawtell, stopping at a roadside stall to buy bananas, and enjoyed ate them at the lookout.
A friendly family of magpies came to us to beg for food so I threw them bits of banana peel and they seemed to enjoy it. The seagulls that showed up shortly after didn’t care for it at all and were FURIOUS we didn’t have chips.
There was a little path down to the beaches, but we only went about halfway and sat at a cute bench, watching the ocean and avoiding the walk back up the hill to the car.
The next day was a public holiday in Queensland, and I was scheduled to leave on the train to Sydney.
Shawn made up the last of our muffins while I showered and went to the jetty for coffee and a bit of sunlight. There were plenty of cute dogs and little regional planes to spot. But eventually it was time to head to the station.
I’d booked a first class ticket from Coffs to Sydney. Usually I book two, because I’m large, but I figured for the short journey I’d be fine. But a few hours into the trip one of the rail staff started hovering around, awkwardly looking at me.
I popped out an earbud.
“I don’t think I have to tell you you’re a big guy,” she says sheepishly.
“There’s another passenger getting on who’s seated next to you. So I’ve moved you a few seats back to your own seat.”
“Lol,” I laughed.
I swapped seats and the rest of the journey was pleasant, but uneventful.